/// <summary> /// Registers a listener for the specified message code. /// Messages without an explicit receiver are broadcasted to all its registered listeners. /// </summary> /// <param name="listener">the listener to add</param> /// <param name="messages">the message codes</param> public void AddListener(ITelegraph listener, params int[] messages) { foreach (int message in messages) { this.AddListener(listener, message); } }
/// <summary> /// Registers a listener for the specified message code. /// Messages without an explicit receiver are broadcasted to all its registered listeners. /// </summary> /// <param name="listener">the listener to add</param> /// <param name="message">the message code</param> public void AddListener(ITelegraph listener, int message) { IList <ITelegraph> listeners; if (!this.messageListeners.TryGetValue(message, out listeners)) { listeners = new List <ITelegraph>(); this.messageListeners.Add(message, listeners); } listeners.Add(listener); // Dispatch messages from registered providers IList <ITelegramProvider> providers; if (this.messageProviders.TryGetValue(message, out providers)) { for (int i = 0, n = providers.Count; i < n; i++) { ITelegramProvider provider = providers[i]; object info = provider.ProvideMessageInfo(message, listener); if (info != null) { ITelegraph sender = info as ITelegraph; this.DispatchMessage(message, 0, sender, listener, info); } } } }
/// <summary> /// Unregister the specified listener for the specified message code /// </summary> /// <param name="listener">the listener to remove</param> /// <param name="message">the message code</param> public void RemoveListener(ITelegraph listener, int message) { IList <ITelegraph> listeners; if (this.messageListeners.TryGetValue(message, out listeners)) { listeners.Remove(listener); } }
/// <summary> /// Given a message, a receiver, a sender and any time delay, this method routes the message to the correct agents (if no delay) /// or stores in the message queue to be dispatched at the correct time /// </summary> /// <param name="message">the message code</param> /// <param name="delay">the delay in seconds</param> /// <param name="sender">the sender of the telegram</param> /// <param name="receiver">the receiver of the telegram; if it's <code>null</code> the telegram is broadcasted to all the receivers registered for the specified message code</param> /// <param name="extraInfo">an optional object</param> /// <param name="needReturnReceipt">whether the return receipt is needed or not</param> public void DispatchMessage( int message, float delay = 0f, ITelegraph sender = null, ITelegraph receiver = null, object extraInfo = null, bool needReturnReceipt = false) { if (sender == null && needReturnReceipt) { throw new ArgumentException("Sender cannot be null when a return receipt is needed"); } // Get a telegram from the pool Telegram telegram = Pool.Obtain(); telegram.Sender = sender; telegram.Receiver = receiver; telegram.Message = message; telegram.ExtraInfo = extraInfo; telegram.ReturnReceiptStatus = needReturnReceipt ? ReturnReceiptStatus.Needed : ReturnReceiptStatus.Unneeded; // If there is no delay, route telegram immediately if (delay <= 0.0f) { // TODO: should we set the timestamp here? // telegram.Timestamp = GDXAI.TimePiece.Time; if (this.DebugEnabled) { float currentTime = GDXAI.TimePiece.Time; Logger.Info("Instant telegram dispatched at time: {0} by {1} for {2}. Message code is " + message, currentTime, sender, receiver); } // Send the telegram to the recipient Discharge(telegram); } else { float currentTime = GDXAI.TimePiece.Time; // Set the timestamp for the delayed telegram telegram.Timestamp = currentTime + delay; // Put the telegram in the queue bool added = this.queue.Add(telegram); // Return it to the pool if has been rejected if (!added) { Pool.Free(telegram); } if (this.DebugEnabled) { if (added) { Logger.Info("Delayed telegram from {0} for {1} recorded at time {2}. Message code is {3}", sender, receiver, currentTime, message); } else { Logger.Info("Delayed telegram from {0} for {1} rejected by the queue. Message code is {2}", sender, receiver, message); } } } }