Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Communication.Operators/CommunicatorBase.cs @ 1502

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

fixed some bugs (#486)

File size: 2.7 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 abstract class CommunicatorBase : OperatorBase {
10    public CommunicatorBase()
11      : base() {
12      AddVariableInfo(new VariableInfo("PeerName", "", typeof(StringData), VariableKind.In));
13      AddVariableInfo(new VariableInfo("Protocol", "", typeof(Protocol), VariableKind.In));
14      AddVariableInfo(new VariableInfo("CurrentState", "", typeof(ProtocolState), VariableKind.In));
15      AddVariableInfo(new VariableInfo("Message", "The message to be sent and/or received. If it is not present the operator will listen for incomming messages.", typeof(Message), VariableKind.New | VariableKind.In | VariableKind.Out | VariableKind.Deleted));
16    }
17
18    public override IOperation Apply(IScope scope) {
19      Protocol protocol = GetVariableValue<Protocol>("Protocol", scope, true);
20      ProtocolState currentState = GetVariableValue<ProtocolState>("CurrentState", scope, true);
21     
22      IVariableInfo info = GetVariableInfo("Message");
23      string actualName = info.ActualName;
24      if (!info.Local)
25        actualName = scope.TranslateName(info.FormalName);
26
27      string peerName = GetVariableValue<StringData>("PeerName", scope, true).Data;
28      Message message = GetVariableValue<Message>("Message", scope, false, false);
29
30      if (message == null) { // RECEIVE MODE (no message present)
31        message = Receive(scope, protocol, currentState);
32        if (message == null) throw new InvalidOperationException("ERROR in Communicator: Message could not be received");
33        if (!info.Local) scope.AddVariable(new Variable(actualName, message));
34        else AddVariable(new Variable(actualName, message));
35      } else { // SEND MODE (message present)
36        if (message.Source.Equals(peerName)) {
37          // originating here, send it
38          Send(scope, protocol, currentState, message);
39          if (!info.Local) scope.RemoveVariable(actualName);
40          else RemoveVariable(actualName);
41          // after sending the message if there is something to be received, apply this operator again
42          if (currentState.Expect.Count > 0) return new AtomicOperation(this, scope);
43        } else throw new ArgumentException("ERROR in Communicator: Message to be sent does not originate from this peer");
44      }
45      return null;
46    }
47
48    protected abstract void Send(IScope scope, Protocol protocol, ProtocolState currentState, Message message);
49    protected abstract Message Receive(IScope scope, Protocol protocol, ProtocolState currentState);
50  }
51}
Note: See TracBrowser for help on using the repository browser.