/* Deferred Messaging Module jhaley 01/19/2011 This set of classes can be used to pass messages between arbitrary objects. The messages are deferrable, with an optional maximum number of dispatches. When a destination responds to a message, either by accepting or refusing it, the source of the message will be notified. */ #ifndef deferred_messages_h__ #define deferred_messages_h__ class classDeferredMessageQueue; class classDeferredMessage; // // classDeferredMessageListener // // Create one derived instance of this abstract class for each object that wants // to send or receive messages. // class classDeferredMessageListener { private: set queues; // only the message queue class is allowed to do this: friend class classDeferredMessageQueue; void AddQueue(classDeferredMessageQueue *queue); void RemoveQueue(classDeferredMessageQueue *queue); public: classDeferredMessageListener(); void ShutDown(); virtual ~classDeferredMessageListener(); // Return a unique name from this routine to globally identify this listener virtual const char *GetName() = 0; // Return true if you can accept the message or false otherwise virtual bool CanAcceptMessage(classDeferredMessage &msg) = 0; // Take action on the message after accepting it. virtual void AcceptMessage(classDeferredMessage &msg) = 0; /* Called on source after recipient acts on the message. The result code can be modified if desired. The value of result should be one of the classDeferredMessage result codes */ virtual void MessageResult(classDeferredMessage &msg, int &result) = 0; }; // // classDeferredMessage // // This class represents a deferrable, refusable, and cancelable message between // two objects. // class classDeferredMessage { private: classDeferredMessageListener *recipient; classDeferredMessageListener *source; string message_name; string message_reason; int dispatch_count; // number of times tried so far int max_dispatch_count; // maximum tries, if not -1 public: // message result codes: enum { RES_DISPATCHED, // recipient accepted the message RES_REFUSED, // recipient refused the message RES_FAILED, // message has not been accepted in max_dispatch_count tries RES_CANCELED // message canceled by recipient }; classDeferredMessage(); classDeferredMessage(classDeferredMessageListener *src, classDeferredMessageListener *dest, const string &msg_name, const string &msg_reason, int max_dispatches = -1); classDeferredMessage(const classDeferredMessage &other); // name and reason identify the type/purpose of the message string GetName(); string GetReason(); // recipient and source; the destination and originator of the message. classDeferredMessageListener *GetRecipient(); classDeferredMessageListener *GetSource(); // dispatching mechanics int GetDispatchCount(); int GetMaxDispatchCount(); void SetMaxDispatchCount(int ct); // AttemptDispatch will try to send the message to the recipient int AttemptDispatch(); // Cancel is called when the recipient cancels messages, such as when it is deleted void Cancel(); }; // // classNoSuchListener // // Exception thrown by classDeferredMessageQueue if an unknown listener is // named in a parameter to CreateMessage. // class classNoSuchListener { }; // // classDeferredMessageQueue // // This class represents a communications channel between arbitrary objects // (an object can even listen for its own events, simply by addressing itself). // class classDeferredMessageQueue { private: TTimer *timer; list deferred_messages; int lock_count; bool use_timer; map listeners; // event handlers void __fastcall timerEvent(TObject *Sender); public: classDeferredMessageQueue(bool p_use_timer, bool enabled, int interval); ~classDeferredMessageQueue(); // listeners void AddListener(classDeferredMessageListener *listener); void RemoveListener(classDeferredMessageListener *listener); void RemoveAllListeners(); classDeferredMessageListener *FindListener(const string &name); // messages classDeferredMessage CreateMessage(const string &source, const string &dest, const string &name, const string &reason, int max_dispatch_count = -1); bool ScheduleMessage(classDeferredMessage &msg); void CancelMessagesFor(classDeferredMessageListener *recipient); void CancelMessagesFrom(classDeferredMessageListener *source); void CancelAllMessages(); void DispatchMessages(); // queue locking semantics void LockQueue(); void UnlockQueue(); bool IsLocked(); bool IsTimerEnabled(); void SetTimerEnabled(bool enabled); Cardinal GetTimerInterval(); void SetTimerInterval(Cardinal interval); }; #endif // EOF