//----------------------------------------------------------------------------- // Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- /* ** Alive and Ticking ** (c) Copyright 2006 Burnt Wasp ** All Rights Reserved. ** ** Filename: dispatcher.h ** Author: Tom Bampton ** Created: 19/8/2006 ** Purpose: ** Message Dispatcher ** */ #include "messaging/message.h" #include "console/console.h" #ifndef _DISPATCHER_H_ #define _DISPATCHER_H_ /// @addtogroup msgsys Message System // @{ ////////////////////////////////////////////////////////////////////////// /// @brief Namespace for the message dispatcher functions ////////////////////////////////////////////////////////////////////////// namespace Dispatcher { // [tom, 2/19/2007] This semi colon prevents VS from auto indenting the comments // below, which is really annoying when you're trying to write docs. ; /// @addtogroup msgsys Message System // @{ ////////////////////////////////////////////////////////////////////////// // Interface for objects that receive messages ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /// @brief Listener interface for objects that receive messages /// /// @see ScriptMsgListener ////////////////////////////////////////////////////////////////////////// class IMessageListener { protected: /// List of queues this listener is registered with. Vector mQueues; public: virtual ~IMessageListener(); ////////////////////////////////////////////////////////////////////////// /// @brief Callback for when messages are received /// /// @param queue The name of the queue the message was dispatched to /// @param msg The type of message /// @param data The data for the message /// @return false to prevent other listeners receiving this message, true otherwise /// @see onMessageObjectReceived() ////////////////////////////////////////////////////////////////////////// virtual bool onMessageReceived(StringTableEntry queue, const char *msg, const char *data) = 0; ////////////////////////////////////////////////////////////////////////// /// @brief Callback for when message objects are received /// /// @param queue The name of the queue the message was dispatched to /// @param msg The message object /// @return false to prevent other listeners receiving this message, true otherwise /// @see onMessageReceived() ////////////////////////////////////////////////////////////////////////// virtual bool onMessageObjectReceived(StringTableEntry queue, Message *msg ) = 0; ////////////////////////////////////////////////////////////////////////// /// @brief Callback for when the listener is added to a queue /// /// The default implementation of onAddToQueue() and onRemoveFromQueue() /// provide tracking of the queues this listener is added to through the /// #mQueues member. Overrides of onAddToQueue() or onRemoveFromQueue() /// should ensure they call the parent implementation in any overrides. /// /// @param queue The name of the queue that the listener added to /// @see onRemoveFromQueue() ////////////////////////////////////////////////////////////////////////// virtual void onAddToQueue(StringTableEntry queue); ////////////////////////////////////////////////////////////////////////// /// @brief Callback for when the listener is removed from a queue /// /// The default implementation of onAddToQueue() and onRemoveFromQueue() /// provide tracking of the queues this listener is added to through the /// #mQueues member. Overrides of onAddToQueue() or onRemoveFromQueue() /// should ensure they call the parent implementation in any overrides. /// /// @param queue The name of the queue the listener was removed from /// @see onAddToQueue() ////////////////////////////////////////////////////////////////////////// virtual void onRemoveFromQueue(StringTableEntry queue); }; ////////////////////////////////////////////////////////////////////////// /// @brief Internal class for tracking message queues ////////////////////////////////////////////////////////////////////////// struct MessageQueue { StringTableEntry mQueueName; VectorPtr mListeners; MessageQueue() : mQueueName("") { } bool isEmpty() { return mListeners.size() == 0; } bool dispatchMessage(const char* event, const char* data) { for(VectorPtr::iterator i = mListeners.begin();i != mListeners.end();i++) { if( !(*i)->onMessageReceived(mQueueName, event, data) ) return false; } return true; } bool dispatchMessageObject(Message *msg) { for(VectorPtr::iterator i = mListeners.begin();i != mListeners.end();i++) { if( !(*i)->onMessageObjectReceived(mQueueName, msg) ) return false; } return true; } }; ////////////////////////////////////////////////////////////////////////// // Message Dispatcher Functions ////////////////////////////////////////////////////////////////////////// /// @name Message Queue Management // @{ ////////////////////////////////////////////////////////////////////////// /// @brief Check if a message queue is registered /// /// @param name The name of the message queue /// @return true if the queue is registered, false otherwise /// @see registerMessageQueue(), unregisterMessageQueue() ////////////////////////////////////////////////////////////////////////// extern bool isQueueRegistered(const char *name); ////////////////////////////////////////////////////////////////////////// /// @brief Register a message queue /// /// @param name The name of the message queue to register /// @see isQueueRegistered(), unregisterMessageQueue() ////////////////////////////////////////////////////////////////////////// extern void registerMessageQueue(const char *name); ////////////////////////////////////////////////////////////////////////// /// @brief Unregister a message queue /// /// @param name The name of the message queue /// @see registerMessageQueue(), isQueueRegistered() ////////////////////////////////////////////////////////////////////////// extern void unregisterMessageQueue(const char *name); ////////////////////////////////////////////////////////////////////////// /// @brief Register a listener with a queue to receive messages /// /// @param queue The name of the queue to register the listener with /// @param listener The listener interface that receives messages /// @return true for success, false otherwise /// @see unregisterMessageListener() ////////////////////////////////////////////////////////////////////////// extern bool registerMessageListener(const char *queue, IMessageListener *listener); ////////////////////////////////////////////////////////////////////////// /// @brief Unregister a listener with a queue /// /// @param queue The name of the queue to unregister the listener /// @param listener The listener interface that was passed to registerMessageListener() /// @see registerMessageListener() ////////////////////////////////////////////////////////////////////////// extern void unregisterMessageListener(const char *queue, IMessageListener *listener); // @} /// @name Message Dispatcher // @{ ////////////////////////////////////////////////////////////////////////// /// @brief Dispatch a message to a queue /// /// @param queue Queue to dispatch the message to /// @param msg Message to dispatch /// @param data Data for message /// @return true for success, false for failure /// @see dispatchMessageObject() ////////////////////////////////////////////////////////////////////////// extern bool dispatchMessage(const char *queue, const char *msg, const char *data); ////////////////////////////////////////////////////////////////////////// /// @brief Dispatch a message object to a queue /// /// @param queue Queue to dispatch the message to /// @param msg Message to dispatch /// @return true for success, false for failure /// @see dispatchMessage() ////////////////////////////////////////////////////////////////////////// extern bool dispatchMessageObject(const char *queue, Message *msg); // @} ////////////////////////////////////////////////////////////////////////// // Internal Functions ////////////////////////////////////////////////////////////////////////// /// @name Internal Functions // @{ ////////////////////////////////////////////////////////////////////////// /// @brief Internal function: Lock the dispatcher mutex. /// @return true for success, false for failure /// @see unlockDispatcherMutex() ////////////////////////////////////////////////////////////////////////// extern bool lockDispatcherMutex(); ////////////////////////////////////////////////////////////////////////// /// @brief Internal function: Unlock the dispatcher mutex. /// @see lockDispatcherMutex() ////////////////////////////////////////////////////////////////////////// extern void unlockDispatcherMutex(); ////////////////////////////////////////////////////////////////////////// /// @brief Internal function: obtain message queue. Dispatcher mutex must be locked. /// /// @param name Name of the queue /// @return Message queue /// @see lockDispatcherMutex(), unlockDispatcherMutex() ////////////////////////////////////////////////////////////////////////// extern MessageQueue *getMessageQueue(const char *name); // @} // @} } // end namespace Dispatcher // @} #endif // _DISPATCHER_H_