Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Communication.Operators/MessageProcessor.cs @ 1207

Last change on this file since 1207 was 1207, checked in by abeham, 15 years ago

fixed some bugs (#486)

File size: 4.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4using HeuristicLab.Core;
5using HeuristicLab.Data;
6using HeuristicLab.Communication.Data;
7
8namespace HeuristicLab.Communication.Operators {
9  public class MessageProcessor : OperatorBase {
10    public override string Description {
11      get {
12        return @"If no ""Message"" is present it will call its first suboperator (communicator) to receive a ""Message"".
13If a locally created ""Message"" is present it will call its first suboperator (communicator) to send it and if a response is expected call itself again to check for it.
14If a received ""Message"" is present it will output it as ""Received"" and create a response ""Message"" if necessary.";
15      }
16    }
17
18    public MessageProcessor()
19      : base() {
20      AddVariableInfo(new VariableInfo("Protocol", "The protocol that is used", typeof(Protocol), VariableKind.In));
21      AddVariableInfo(new VariableInfo("PeerName", "The name of this peer", typeof(StringData), VariableKind.In));
22      AddVariableInfo(new VariableInfo("Message", "The message that is to be processed", typeof(Message), VariableKind.New | VariableKind.Out | VariableKind.Deleted));
23      AddVariableInfo(new VariableInfo("Received", "A message that has been received is saved for further processing", typeof(Message), VariableKind.New));
24    }
25
26    public override IOperation Apply(IScope scope) {
27      Message message = GetVariableValue<Message>("Message", scope, false, false);
28      if (message == null) { // Case 1: No message present -> call first SubOperator to create one (listen for one)
29        if (SubOperators.Count > 0) {
30          CompositeOperation co = new CompositeOperation();
31          co.AddOperation(new AtomicOperation(SubOperators[0], scope));
32          co.AddOperation(new AtomicOperation(this, scope));
33          return co;
34        } else throw new InvalidOperationException("ERROR in MessageProcessor: No message present and no suboperator defined which could listen and create one");
35      } else {
36        Protocol protocol = GetVariableValue<Protocol>("Protocol", scope, true);
37        if (message.Protocol.Equals(protocol.Name)) {
38          string peerName = GetVariableValue<StringData>("PeerName", scope, true).Data;
39          if (message.Source.Equals(peerName)) { // Case 2: A locally created message is present
40            if (message.Expect.Count > 0) { // Subcase 2.1: Expects response, so send it and call self afterwards to retrieve the response
41              CompositeOperation co = new CompositeOperation();
42              co.AddOperation(new AtomicOperation(SubOperators[0], scope));
43              co.AddOperation(new AtomicOperation(this, scope));
44              return co;
45            } else { // Subcase 2.2: No response expected, just send it
46              return new AtomicOperation(SubOperators[0], scope);
47            }
48          } else { // Case 3: A remotely created message received -> save message, and if necessary create response message
49            if (message.Give.Count > 0) { // if data has been added for this
50              IVariableInfo receivedInfo = GetVariableInfo("Received");
51              if (receivedInfo.Local) {
52                AddVariable(new Variable(receivedInfo.ActualName, (IItem)message.Clone()));
53              } else {
54                scope.AddVariable(new Variable(scope.TranslateName(receivedInfo.FormalName), (IItem)message.Clone()));
55              }
56            }
57            if (message.Expect.Count > 0) { // if data has been requested, create a response
58              message.Give = message.Expect;
59              message.Expect = new List<IVariable>();
60              message.Destination = message.Source;
61              message.Source = peerName;
62              message.Timestamp = DateTime.Now;
63            } else { // otherwise delete the message
64              IVariableInfo messageInfo = GetVariableInfo("Message");
65              if (messageInfo.Local) {
66                RemoveVariable(messageInfo.ActualName);
67              } else {
68                scope.RemoveVariable(scope.TranslateName(messageInfo.ActualName));
69              }
70            }
71          }
72        } else throw new InvalidOperationException("ERROR in MessageProcessor: Remote peer is using different protocol");
73      }
74      return null;
75    }
76  }
77}
Note: See TracBrowser for help on using the repository browser.