/// <summary> /// Create a carrier of the specified protocol and signal if a receiver currently exists. /// Note that because a carrier might not be created, there is no return value for this method. /// </summary> /// <param name="from">The source receptor. Cay be null.</param> /// <param name="protocol">The protocol.</param> /// <param name="signal">The signal in the protocol's format.</param> public void CreateCarrierIfReceiver(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal) { if (TargetReceptorExistsFor(ReceptorFromInstance(from), protocol)) { CreateCarrier(from, protocol, signal); } }
/// <summary> /// Internal carrier creation. This includes the "stopRecursion" flag to prevent wildcard receptors from receiving ad-infinitum their own emissions. /// </summary> protected ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, bool stopRecursion, bool isSystemMessage = false, ICarrier parentCarrier = null, bool emitSubElements = true) { Carrier carrier = null; if (from.GetEnabledEmittedProtocols().Any(p => p.Protocol == protocol.DeclTypeName) || isSystemMessage) { carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); // ************ MOVED TO A: ************** // The reason this was moved is so that we fire NewCarrier only for actual receptors with protocols enabled for that receptor. // TODO: However, this means that we no longer queue protocols for which we have no receptors. Not sure if we actually want this particular feature. // NewCarrier.Fire(this, new NewCarrierEventArgs(from, carrier)); // We pass along the stopRecursion flag to prevent wild-card carrier receptor from receiving their own emissions, which would result in a new carrier, // ad-infinitum. ProcessReceptors(from, carrier, stopRecursion); } // Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. if (!isSystemMessage && emitSubElements) { // The carrier might be null if there's no receiver for the parent carrier. In this case, we need to create a dummy carrier so we have a parent. if (carrier == null) { carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); } CreateCarriersForSemanticElements(from, protocol, protocol.DeclTypeName, signal, stopRecursion, carrier); } return(carrier); }
/// <summary> /// For instances that the application defines and that implement IReceptorInstance, /// use this constructor to specify the existing instance. /// </summary> public Receptor(string name, IReceptorInstance inst) { Name = name; Instance = inst; Instantiated = true; Enabled = true; }
/// <summary> /// Add an existing implementor of IReceptorInstance. Call this method when registering /// application-level instances that are themselves receptors, such as models, controllers, /// views, etc. /// </summary> public void RegisterReceptor(string name, IReceptorInstance inst) { Receptor r = new Receptor(name, inst); r.EnabledStateChanged += WhenEnabledStateChanged; receptors.Add(r); }
protected void CreateCarrierIfReceiver(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, ICarrier parentCarrier, bool emitSubElements = true) { if (from.GetEnabledEmittedProtocols().Any(p => p.Protocol == protocol.DeclTypeName)) { if (TargetReceptorExistsFor(ReceptorFromInstance(from), protocol, protocol.DeclTypeName == protocolPath)) { // This call will recurse for us. // CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, bool stopRecursion, bool isSystemMessage = false, ICarrier parentCarrier = null) CreateCarrier(from, protocol, protocolPath, signal, false, false, parentCarrier, emitSubElements); } else { if (emitSubElements) { // Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. // We do this even if there isn't a target for the top-level receptor. // However, we do create a Carrier instance as the parent so the child can reference it if necessary. Carrier carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); CreateCarriersForSemanticElements(from, protocol, protocolPath, signal, false, carrier); } } } else { if (emitSubElements) { // Create a Carrier instance as the parent so the child can reference it if necessary. Carrier carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); CreateCarriersForSemanticElements(from, protocol, protocolPath, signal, false, carrier); } } }
/// <summary> /// Create a carrier of the specified protocol and signal. /// </summary> /// <param name="from">The source receptor. Cay be null.</param> /// <param name="protocol">The protocol.</param> /// <param name="signal">The signal in the protocol's format.</param> public ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal) { // This calls the internal method with recursion set to false. We don't want to expose this // flag, so this method is a public front, as receptors should never set the "stop recursion" flag // to true when creating carriers. ICarrier carrier = CreateCarrier(from, protocol, signal, false); return(carrier); }
/// <summary> /// Create a carrier of the specified protocol and signal. /// </summary> /// <param name="from">The source receptor. Cay be null.</param> /// <param name="protocol">The protocol.</param> /// <param name="signal">The signal in the protocol's format.</param> public ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal, ICarrier parentCarrier = null, bool emitSubElements = true) { // This calls the internal method with recursion set to false. We don't want to expose this // flag, so this method is a public front, as receptors should never set the "stop recursion" flag // to true when creating carriers. // TODO: Improve these "is it a system message" tests -- figure out how to get rid of these hardcoded string. ICarrier carrier = CreateCarrier(from, protocol, protocol.DeclTypeName, signal, false, protocol.DeclTypeName == "SystemMessage" || from.Name == "DropReceptor", parentCarrier, emitSubElements); return(carrier); }
/// <summary> /// Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. /// </summary> protected void CreateCarriersForSemanticElements(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, bool stopRecursion, ICarrier parentCarrier) { protocol.SemanticElements.ForEach(se => { dynamic subsignal = SemanticTypeSystem.Clone(signal, se); // Clone the contents of the signal's semantic element into the subsignal. // We may have a null child, in which case, don't drill any further into the structure! if (subsignal != null) { ISemanticTypeStruct semStruct = SemanticTypeSystem.GetSemanticTypeStruct(se.Name); // Will result in recursive calls for all sub-semantic types. CreateCarrierIfReceiver(from, semStruct, protocolPath + "." + semStruct.DeclTypeName, subsignal, parentCarrier); } }); }
/// <summary> /// Internal carrier creation. This includes the "stopRecursion" flag to prevent wildcard receptors from receiving ad-infinitum their own emissions. /// </summary> protected ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal, bool stopRecursion) { Carrier carrier = new Carrier(protocol, signal); NewCarrier.Fire(this, new NewCarrierEventArgs(from, carrier)); // We pass along the stopRecursion flag to prevent wild-card carrier receptor from receiving their own emissions, which would result in a new carrier, // ad-infinitum. ProcessReceptors(from, carrier, stopRecursion); // Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. CreateCarriersForSemanticElements(from, protocol, signal, stopRecursion); return(carrier); }
/// <summary> /// Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. /// </summary> protected void CreateCarriersForSemanticElements(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal, bool stopRecursion) { protocol.SemanticElements.ForEach(se => { ISemanticTypeStruct semStruct = SemanticTypeSystem.GetSemanticTypeStruct(se.Name); // Currently, we can only do this if the subelement contains one and only one native or SE element. // TODO: Fix this, as it ends up throwing an exception, see SemanticElement.cs, GetValue "Getting a value on a semantic type requires that the semantic type defines one and only one native type or child semantic type in order to resolve the native type property whose value is to be set." if (semStruct.NativeTypes.Count + semStruct.SemanticElements.Count == 1) { dynamic subsignal = SemanticTypeSystem.Create(se.Name); object val = se.GetValue(SemanticTypeSystem, signal); se.SetValue(SemanticTypeSystem, subsignal, val); CreateCarrierIfReceiver(from, semStruct, subsignal); } }); }
public void ProcessCarrier(ICarrier carrier) { switch (carrier.Protocol.DeclTypeName) { case "SystemMessage": { string action = carrier.Signal.Action; string data = carrier.Signal.Data; IReceptorInstance receptorInstance = carrier.Signal.Source; if (action == "Flyout") { VisualizerController.View.Flyout(data, receptorInstance); } break; } case "CarrierAnimation": { Action action = carrier.Signal.Process; IReceptorInstance from = carrier.Signal.From; IReceptorInstance to = carrier.Signal.To; ICarrier outCarrier = carrier.Signal.Carrier; VisualizerController.View.AnimateCarrier(action, from, to, outCarrier); break; } case "SystemShowImage": { IReceptorInstance target = carrier.Signal.From; Image image = carrier.Signal.Image; VisualizerController.View.AddImage(target, image); break; } case "HaveImageMetadata": { VisualizerController.View.ProcessImageMetadata(carrier.Signal); break; } } }
/// <summary> /// Return an action representing what to do for a new carrier/protocol. /// </summary> protected Action GetProcessAction(IReceptorInstance from, Carrier carrier, bool stopRecursion) { // Construct an action... Action action = new Action(() => { // Get the receptors receiving the protocol. List <IReceptorConnection> receptors = GetTargetReceptorsFor(ReceptorFromInstance(from), carrier); // For each receptor that is enabled... receptors.ForEach(receptor => { // The action is "ProcessCarrier". // TODO: *** Pass in the carrier, not the carrier's fields!!! *** // ************* A: MOVED HERE ************ NewCarrier.Fire(this, new NewCarrierEventArgs(from, carrier)); Action process = new Action(() => receptor.Receptor.Instance.ProcessCarrier(carrier)); // TODO: This flag is tied in with the visualizer, we should extricate this flag and logic. if (receptor.Receptor.Instance.IsHidden) { // Don't visualize carriers to hidden receptors. process(); } else if (!stopRecursion) { // TODO: This should be handled externally somehow. // Defer the action, such that the visualizer can invoke it when it determines the carrier rendering to the receiving receptor has completed. ISemanticTypeStruct protocol = SemanticTypeSystem.GetSemanticTypeStruct("CarrierAnimation"); dynamic signal = SemanticTypeSystem.Create("CarrierAnimation"); signal.Process = process; signal.From = from; signal.To = receptor.Receptor.Instance; signal.Carrier = carrier; // Simulate coming from the system, as it IS a system message. // Also note that the "stop recursion" flag is set to true on a receptor defining "receives everything" ("*"). CreateCarrier(from, protocol, protocol.DeclTypeName, signal, receptor.Receptor.Instance.GetEnabledReceiveProtocols().Select(rp => rp.Protocol).Contains("*"), true); } }); }); return(action); }
/// <summary> /// Given a carrier, if there are receptors for the carrier's protocol, act upon the carrier immediately. /// If there are no receptors for the protocol, queue the carrier. /// </summary> protected void ProcessReceptors(IReceptorInstance from, Carrier carrier, bool stopRecursion) { // Get the action that we are supposed to perform on the carrier. Action action = GetProcessAction(from, carrier, stopRecursion); List <IReceptor> receptors = GetTargetReceptorsFor(ReceptorFromInstance(from), carrier); // If we have any enabled receptor for this carrier (a mapping of carrier to receptor list exists and receptors actually exist in that map)... if (receptors.Count > 0) { // ...perform the action. action(); } else { // ...othwerise, queue up the carrier for when there is a receptor for it. queuedCarriers.Add(new QueuedCarrierAction() { From = ReceptorFromInstance(from), Carrier = carrier, Action = action }); } }
/// <summary> /// Given a carrier, if there are receptors for the carrier's protocol, act upon the carrier immediately. /// If there are no receptors for the protocol, queue the carrier. /// </summary> protected void ProcessReceptors(IReceptorInstance from, Carrier carrier, bool stopRecursion) { // Get the action that we are supposed to perform on the carrier. Action action = GetProcessAction(from, carrier, stopRecursion); IReceptor receptor = ReceptorFromInstance(from); // Some bullet proofing that was revealed in unit testing. if (receptor != null) { List <IReceptorConnection> receptors = GetTargetReceptorsFor(ReceptorFromInstance(from), carrier); // If we have any enabled receptor for this carrier (a mapping of carrier to receptor list exists and receptors actually exist in that map)... if (receptors.Count > 0) { // ...perform the action. action(); } else { // ...othwerise, queue up the carrier for when there is a receptor for it. queuedCarriers.Add(new QueuedCarrierAction() { From = ReceptorFromInstance(from), Carrier = carrier, Action = action }); } } else { // The "from" receptor is null, which is an invalid condition occurring during unit testing. // Regardless, queue the carrier. queuedCarriers.Add(new QueuedCarrierAction() { From = null, Carrier = carrier, Action = action }); } }
public void RegisterReceptor(string name, IReceptorInstance inst) { receptorSystem.RegisterReceptor(name, inst); }
public void Remove(IReceptorInstance receptorInstance) { receptorSystem.Remove(receptorInstance); }
public ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal) { return(receptorSystem.CreateCarrier(from, protocol, signal)); }
public void CreateCarrierIfReceiver(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal) { receptorSystem.CreateCarrierIfReceiver(from, protocol, signal); }
public NewCarrierEventArgs(IReceptorInstance from, ICarrier carrier) { From = from; Carrier = carrier; }
public IntervalTimer(IReceptorSystem rsys, IReceptorInstance receptor) { this.rsys = rsys; this.receptor = receptor; }
/// <summary> /// Create a carrier of the specified protocol and signal if a receiver currently exists. /// Note that because a carrier might not be created, there is no return value for this method. /// </summary> /// <param name="from">The source receptor. Cay be null.</param> /// <param name="protocol">The protocol.</param> /// <param name="signal">The signal in the protocol's format.</param> public void CreateCarrierIfReceiver(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal, ICarrier parentCarrier = null, bool emitSubElements = true) { CreateCarrierIfReceiver(from, protocol, protocol.DeclTypeName, signal, parentCarrier, emitSubElements); }
/// <summary> /// Return an action representing what to do for a new carrier/protocol. /// </summary> protected Action GetProcessAction(IReceptorInstance from, Carrier carrier, bool stopRecursion, bool isRoot) { // Construct an action... Action action = new Action(() => { // Get the receptors receiving the protocol. List<IReceptorConnection> receptors = GetTargetReceptorsFor(ReceptorFromInstance(from), carrier, isRoot); // For each receptor that is enabled... receptors.ForEach(receptor => { // The action is "ProcessCarrier". // TODO: *** Pass in the carrier, not the carrier's fields!!! *** // ************* A: MOVED HERE ************ NewCarrier.Fire(this, new NewCarrierEventArgs(from, carrier)); Action process = new Action(() => receptor.Receptor.Instance.ProcessCarrier(carrier)); // TODO: This flag is tied in with the visualizer, we should extricate this flag and logic. if (receptor.Receptor.Instance.IsHidden) { // Don't visualize carriers to hidden receptors. process(); } else if (!stopRecursion) { // TODO: This should be handled externally somehow. // Defer the action, such that the visualizer can invoke it when it determines the carrier rendering to the receiving receptor has completed. ISemanticTypeStruct protocol = SemanticTypeSystem.GetSemanticTypeStruct("CarrierAnimation"); dynamic signal = SemanticTypeSystem.Create("CarrierAnimation"); signal.Process = process; signal.From = from; signal.To = receptor.Receptor.Instance; signal.Carrier = carrier; // Simulate coming from the system, as it IS a system message. // Also note that the "stop recursion" flag is set to true on a receptor defining "receives everything" ("*"). CreateCarrier(from, protocol, protocol.DeclTypeName, signal, receptor.Receptor.Instance.GetEnabledReceiveProtocols().Select(rp=>rp.Protocol).Contains("*"), true); } }); }); return action; }
/// <summary> /// Remove the receptor container of the specified instance. /// </summary> /// <param name="receptorInstance"></param> public void Remove(IReceptorInstance receptorInstance) { // Clone the list because the master list will change. Remove((Receptor)ReceptorFromInstance(receptorInstance)); }
/// <summary> /// Create a carrier of the specified protocol and signal. /// </summary> /// <param name="from">The source receptor. Cay be null.</param> /// <param name="protocol">The protocol.</param> /// <param name="signal">The signal in the protocol's format.</param> public ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, dynamic signal, ICarrier parentCarrier = null, bool emitSubElements = true) { // This calls the internal method with recursion set to false. We don't want to expose this // flag, so this method is a public front, as receptors should never set the "stop recursion" flag // to true when creating carriers. // TODO: Improve these "is it a system message" tests -- figure out how to get rid of these hardcoded string. ICarrier carrier = CreateCarrier(from, protocol, protocol.DeclTypeName, signal, false, protocol.DeclTypeName=="SystemMessage" || from.Name=="DropReceptor", parentCarrier, emitSubElements); return carrier; }
protected void CreateCarrierIfReceiver(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, ICarrier parentCarrier, bool emitSubElements = true) { if (from.GetEnabledEmittedProtocols().Any(p => p.Protocol == protocol.DeclTypeName)) { if (TargetReceptorExistsFor(ReceptorFromInstance(from), protocol, protocol.DeclTypeName == protocolPath)) { // This call will recurse for us. // CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, bool stopRecursion, bool isSystemMessage = false, ICarrier parentCarrier = null) CreateCarrier(from, protocol, protocolPath, signal, false, false, parentCarrier, emitSubElements, protocol.DeclTypeName == protocolPath); } else { if (emitSubElements) { // Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. // We do this even if there isn't a target for the top-level receptor. // However, we do create a Carrier instance as the parent so the child can reference it if necessary. Carrier carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); CreateCarriersForSemanticElements(from, protocol, protocolPath, signal, false, carrier); } } } else { if (emitSubElements) { // Create a Carrier instance as the parent so the child can reference it if necessary. Carrier carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); CreateCarriersForSemanticElements(from, protocol, protocolPath, signal, false, carrier); } } }
/// <summary> /// Internal carrier creation. This includes the "stopRecursion" flag to prevent wildcard receptors from receiving ad-infinitum their own emissions. /// </summary> protected ICarrier CreateCarrier(IReceptorInstance from, ISemanticTypeStruct protocol, string protocolPath, dynamic signal, bool stopRecursion, bool isSystemMessage = false, ICarrier parentCarrier = null, bool emitSubElements = true, bool isRoot = true) { Carrier carrier = null; if (from.GetEnabledEmittedProtocols().Any(p => p.Protocol == protocol.DeclTypeName) || isSystemMessage) { carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); // ************ MOVED TO A: ************** // The reason this was moved is so that we fire NewCarrier only for actual receptors with protocols enabled for that receptor. // TODO: However, this means that we no longer queue protocols for which we have no receptors. Not sure if we actually want this particular feature. // NewCarrier.Fire(this, new NewCarrierEventArgs(from, carrier)); // We pass along the stopRecursion flag to prevent wild-card carrier receptor from receiving their own emissions, which would result in a new carrier, // ad-infinitum. ProcessReceptors(from, carrier, stopRecursion, isRoot); } // Recurse into SE's of the protocol and emit carriers for those as well, if a receiver exists. if (!isSystemMessage && emitSubElements) { // The carrier might be null if there's no receiver for the parent carrier. In this case, we need to create a dummy carrier so we have a parent. if (carrier == null) { carrier = new Carrier(protocol, protocolPath, signal, parentCarrier); } CreateCarriersForSemanticElements(from, protocol, protocol.DeclTypeName, signal, stopRecursion, carrier); } return carrier; }
protected IReceptor ReceptorFromInstance(IReceptorInstance inst) { return(receptors.SingleOrDefault(r => r.Instance == inst)); }
/// <summary> /// Given a carrier, if there are receptors for the carrier's protocol, act upon the carrier immediately. /// If there are no receptors for the protocol, queue the carrier. /// </summary> protected void ProcessReceptors(IReceptorInstance from, Carrier carrier, bool stopRecursion, bool isRoot) { // Get the action that we are supposed to perform on the carrier. Action action = GetProcessAction(from, carrier, stopRecursion, isRoot); IReceptor receptor = ReceptorFromInstance(from); // Some bullet proofing that was revealed in unit testing. if (receptor != null) { List<IReceptorConnection> receptors = GetTargetReceptorsFor(ReceptorFromInstance(from), carrier, isRoot); // If we have any enabled receptor for this carrier (a mapping of carrier to receptor list exists and receptors actually exist in that map)... if (receptors.Count > 0) { // ...perform the action. action(); } else { // ...othwerise, queue up the carrier for when there is a receptor for it. queuedCarriers.Add(new QueuedCarrierAction() { From = ReceptorFromInstance(from), Carrier = carrier, Action = action }); } } else { // The "from" receptor is null, which is an invalid condition occurring during unit testing. // Regardless, queue the carrier. queuedCarriers.Add(new QueuedCarrierAction() { From = null, Carrier = carrier, Action = action }); } }
protected IReceptor ReceptorFromInstance(IReceptorInstance inst) { return receptors.SingleOrDefault(r => r.Instance == inst); }