[704] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Text;
|
---|
| 4 | using HeuristicLab.Core;
|
---|
| 5 | using HeuristicLab.Data;
|
---|
| 6 | using HeuristicLab.Communication.Data;
|
---|
| 7 |
|
---|
| 8 | namespace 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 |
|
---|
[1207] | 30 | if (message == null) { // RECEIVE MODE (no message present)
|
---|
[704] | 31 | message = Receive(scope, protocol, currentState);
|
---|
[1207] | 32 | if (message == null) throw new InvalidOperationException("ERROR in Communicator: Message could not be received");
|
---|
[704] | 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 | }
|
---|