dispatcher.cpp
Engine/source/util/messaging/dispatcher.cpp
Classes:
class
Internal class used by the dispatcher.
Namespaces:
namespace
Namespace for the message dispatcher functions.
Public Defines
define
gDispatchData() _dispatcherGetGDispatchData()
Public Functions
DefineEngineFunction(dispatchMessage , bool , (const char *queueName, const char *message, const char *data) , ("") , "(string queueName, string message, string data)" "@brief <a href="/coding/file/windispatch_8h/#windispatch_8h_1a87cb262856b561a9d947228298d12a22">Dispatch</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> message <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName Queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dispatch the message <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param message <a href="/coding/class/classmessage/">Message</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatch\n</a>" "@param data Data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n</a>" "@return True <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> success, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failure\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatchMessageObject\n</a>" " @ingroup Messaging" )
DefineEngineFunction(dispatchMessageObject , bool , (const char *queueName, const char *message) , ("", "") , "(string queueName, string message)" "@brief <a href="/coding/file/windispatch_8h/#windispatch_8h_1a87cb262856b561a9d947228298d12a22">Dispatch</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> message object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName Queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dispatch the message <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param message <a href="/coding/class/classmessage/">Message</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatch\n</a>" "@return true <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> success, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failure\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatchMessage\n</a>" " @ingroup Messaging" )
DefineEngineFunction(isQueueRegistered , bool , (const char *queueName) , "(string queueName)" "@brief Determines <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher queue <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
DefineEngineFunction(registerMessageListener , bool , (const char *queueName, const char *listenerName) , "(string queueName, string listener)" "@brief Registers an event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach listener <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param listener Name of event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">messenger\n</a>" "@ingroup Messaging" )
DefineEngineFunction(registerMessageQueue , void , (const char *queueName) , "(string queueName)" "@brief Registeres <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
DefineEngineFunction(unregisterMessageListener , void , (const char *queueName, const char *listenerName) , "(string queueName, string listener)" "@brief Unregisters an event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@param listener Name of event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">messenger\n</a>" "@ingroup Messaging" )
DefineEngineFunction(unregisterMessageQueue , void , (const char *queueName) , "(string queueName)" "@brief Unregisters <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
Detailed Description
Public Defines
gDispatchData() _dispatcherGetGDispatchData()
Public Functions
DefineEngineFunction(dispatchMessage , bool , (const char *queueName, const char *message, const char *data) , ("") , "(string queueName, string message, string data)" "@brief <a href="/coding/file/windispatch_8h/#windispatch_8h_1a87cb262856b561a9d947228298d12a22">Dispatch</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> message <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName Queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dispatch the message <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param message <a href="/coding/class/classmessage/">Message</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatch\n</a>" "@param data Data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n</a>" "@return True <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> success, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failure\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatchMessageObject\n</a>" " @ingroup Messaging" )
DefineEngineFunction(dispatchMessageObject , bool , (const char *queueName, const char *message) , ("", "") , "(string queueName, string message)" "@brief <a href="/coding/file/windispatch_8h/#windispatch_8h_1a87cb262856b561a9d947228298d12a22">Dispatch</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> message object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName Queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dispatch the message <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param message <a href="/coding/class/classmessage/">Message</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatch\n</a>" "@return true <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> success, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failure\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">dispatchMessage\n</a>" " @ingroup Messaging" )
DefineEngineFunction(isQueueRegistered , bool , (const char *queueName) , "(string queueName)" "@brief Determines <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher queue <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
DefineEngineFunction(registerMessageListener , bool , (const char *queueName, const char *listenerName) , "(string queueName, string listener)" "@brief Registers an event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of queue <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attach listener <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to\n</a>" "@param listener Name of event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">messenger\n</a>" "@ingroup Messaging" )
DefineEngineFunction(registerMessageQueue , void , (const char *queueName) , "(string queueName)" "@brief Registeres <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
DefineEngineFunction(unregisterMessageListener , void , (const char *queueName, const char *listenerName) , "(string queueName, string listener)" "@brief Unregisters an event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">message\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@param listener Name of event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">messenger\n</a>" "@ingroup Messaging" )
DefineEngineFunction(unregisterMessageQueue , void , (const char *queueName) , "(string queueName)" "@brief Unregisters <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> dispatcher <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n\n</a>" "@param queueName <a href="/coding/class/classstring/">String</a> containing the name of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queue\n</a>" "@ingroup Messaging" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "util/messaging/dispatcher.h" 26 27#include "platform/threads/mutex.h" 28#include "core/tSimpleHashTable.h" 29#include "core/util/safeDelete.h" 30#include "console/engineAPI.h" 31 32namespace Dispatcher 33{ 34 35//----------------------------------------------------------------------------- 36// IMessageListener Methods 37//----------------------------------------------------------------------------- 38 39IMessageListener::~IMessageListener() 40{ 41 for(S32 i = 0;i < mQueues.size();i++) 42 { 43 unregisterMessageListener(mQueues[i], this); 44 } 45} 46 47void IMessageListener::onAddToQueue(StringTableEntry queue) 48{ 49 // [tom, 8/20/2006] The dispatcher won't let us get added twice, so no need 50 // to worry about it here. 51 52 mQueues.push_back(queue); 53} 54 55void IMessageListener::onRemoveFromQueue(StringTableEntry queue) 56{ 57 for(S32 i = 0;i < mQueues.size();i++) 58 { 59 if(mQueues[i] == queue) 60 { 61 mQueues.erase(i); 62 return; 63 } 64 } 65} 66 67//----------------------------------------------------------------------------- 68// Global State 69//----------------------------------------------------------------------------- 70 71//----------------------------------------------------------------------------- 72/// @brief Internal class used by the dispatcher 73//----------------------------------------------------------------------------- 74typedef struct _DispatchData 75{ 76 void *mMutex; 77 SimpleHashTable<MessageQueue> mQueues; 78 U32 mLastAnonQueueID; 79 80 _DispatchData() 81 { 82 mMutex = Mutex::createMutex(); 83 mLastAnonQueueID = 0; 84 } 85 86 ~_DispatchData() 87 { 88 if(Mutex::lockMutex( mMutex ) ) 89 { 90 mQueues.clearTables(); 91 92 Mutex::unlockMutex( mMutex ); 93 } 94 95 Mutex::destroyMutex( mMutex ); 96 //SAFE_DELETE(mMutex); 97 mMutex = NULL; 98 } 99 100 const char *makeAnonQueueName() 101 { 102 char buf[512]; 103 dSprintf(buf, sizeof(buf), "AnonQueue.%lu", mLastAnonQueueID++); 104 return StringTable->insert(buf); 105 } 106} _DispatchData; 107 108static _DispatchData& _dispatcherGetGDispatchData() 109{ 110 static _DispatchData dispatchData; 111 return dispatchData; 112} 113 114#define gDispatchData _dispatcherGetGDispatchData() 115 116 117//----------------------------------------------------------------------------- 118// Queue Registration 119//----------------------------------------------------------------------------- 120 121bool isQueueRegistered(const char *name) 122{ 123 MutexHandle mh; 124 if(mh.lock(gDispatchData.mMutex, true)) 125 { 126 return gDispatchData.mQueues.retreive(name) != NULL; 127 } 128 129 return false; 130} 131 132void registerMessageQueue(const char *name) 133{ 134 if(isQueueRegistered(name)) 135 return; 136 137 if(Mutex::lockMutex( gDispatchData.mMutex, true )) 138 { 139 MessageQueue *queue = new MessageQueue; 140 queue->mQueueName = StringTable->insert(name); 141 gDispatchData.mQueues.insert(queue, name); 142 143 Mutex::unlockMutex( gDispatchData.mMutex ); 144 } 145} 146 147extern const char * registerAnonMessageQueue() 148{ 149 const char *name = NULL; 150 if(Mutex::lockMutex( gDispatchData.mMutex, true )) 151 { 152 name = gDispatchData.makeAnonQueueName(); 153 Mutex::unlockMutex( gDispatchData.mMutex ); 154 } 155 156 if(name) 157 registerMessageQueue(name); 158 159 return name; 160} 161 162void unregisterMessageQueue(const char *name) 163{ 164 MutexHandle mh; 165 if(mh.lock(gDispatchData.mMutex, true)) 166 { 167 MessageQueue *queue = gDispatchData.mQueues.remove(name); 168 if(queue == NULL) 169 return; 170 171 // Tell the listeners about it 172 for(S32 i = 0;i < queue->mListeners.size();i++) 173 { 174 queue->mListeners[i]->onRemoveFromQueue(name); 175 } 176 177 delete queue; 178 } 179} 180 181//----------------------------------------------------------------------------- 182// Message Listener Registration 183//----------------------------------------------------------------------------- 184 185bool registerMessageListener(const char *queue, IMessageListener *listener) 186{ 187 if(! isQueueRegistered(queue)) 188 registerMessageQueue(queue); 189 190 MutexHandle mh; 191 192 if(! mh.lock(gDispatchData.mMutex, true)) 193 return false; 194 195 MessageQueue *q = gDispatchData.mQueues.retreive(queue); 196 if(q == NULL) 197 { 198 Con::errorf("Dispatcher::registerMessageListener - Queue '%s' not found?! It should have been added automatically!", queue); 199 return false; 200 } 201 202 for(VectorPtr<IMessageListener *>::iterator i = q->mListeners.begin();i != q->mListeners.end();i++) 203 { 204 if(*i == listener) 205 return false; 206 } 207 208 q->mListeners.push_front(listener); 209 listener->onAddToQueue(StringTable->insert(queue)); 210 return true; 211} 212 213void unregisterMessageListener(const char *queue, IMessageListener *listener) 214{ 215 if(! isQueueRegistered(queue)) 216 return; 217 218 MutexHandle mh; 219 220 if(! mh.lock(gDispatchData.mMutex, true)) 221 return; 222 223 MessageQueue *q = gDispatchData.mQueues.retreive(queue); 224 if(q == NULL) 225 return; 226 227 for(VectorPtr<IMessageListener *>::iterator i = q->mListeners.begin();i != q->mListeners.end();i++) 228 { 229 if(*i == listener) 230 { 231 listener->onRemoveFromQueue(StringTable->insert(queue)); 232 q->mListeners.erase(i); 233 return; 234 } 235 } 236} 237 238//----------------------------------------------------------------------------- 239// Dispatcher 240//----------------------------------------------------------------------------- 241 242bool dispatchMessage( const char* queue, const char* msg, const char* data) 243{ 244 AssertFatal( queue != NULL, "Dispatcher::dispatchMessage - Got a NULL queue name" ); 245 AssertFatal( msg != NULL, "Dispatcher::dispatchMessage - Got a NULL message" ); 246 247 MutexHandle mh; 248 249 if(! mh.lock(gDispatchData.mMutex, true)) 250 return true; 251 252 MessageQueue *q = gDispatchData.mQueues.retreive(queue); 253 if(q == NULL) 254 { 255 Con::errorf("Dispatcher::dispatchMessage - Attempting to dispatch to unknown queue '%s'", queue); 256 return true; 257 } 258 259 return q->dispatchMessage(msg, data); 260} 261 262 263bool dispatchMessageObject(const char *queue, Message *msg) 264{ 265 MutexHandle mh; 266 267 if(msg == NULL) 268 return true; 269 270 msg->addReference(); 271 272 if(! mh.lock(gDispatchData.mMutex, true)) 273 { 274 msg->freeReference(); 275 return true; 276 } 277 278 MessageQueue *q = gDispatchData.mQueues.retreive(queue); 279 if(q == NULL) 280 { 281 Con::errorf("Dispatcher::dispatchMessage - Attempting to dispatch to unknown queue '%s'", queue); 282 msg->freeReference(); 283 return true; 284 } 285 286 // [tom, 8/19/2006] Make sure that the message is registered with the sim, since 287 // when it's ref count is zero it'll be deleted with deleteObject() 288 if(! msg->isProperlyAdded()) 289 { 290 SimObjectId id = Message::getNextMessageID(); 291 if(id != 0xffffffff) 292 msg->registerObject(id); 293 else 294 { 295 Con::errorf("dispatchMessageObject: Message was not registered and no more object IDs are available for messages"); 296 297 msg->freeReference(); 298 return false; 299 } 300 } 301 302 bool bResult = q->dispatchMessageObject(msg); 303 msg->freeReference(); 304 305 return bResult; 306} 307 308//----------------------------------------------------------------------------- 309// Internal Functions 310//----------------------------------------------------------------------------- 311 312MessageQueue * getMessageQueue(const char *name) 313{ 314 return gDispatchData.mQueues.retreive(name); 315} 316 317extern bool lockDispatcherMutex() 318{ 319 return Mutex::lockMutex(gDispatchData.mMutex); 320} 321 322extern void unlockDispatcherMutex() 323{ 324 Mutex::unlockMutex(gDispatchData.mMutex); 325} 326 327} // end namespace Dispatcher 328 329//----------------------------------------------------------------------------- 330// Console Methods 331//----------------------------------------------------------------------------- 332 333using namespace Dispatcher; 334 335DefineEngineFunction( isQueueRegistered, bool, (const char * queueName), , "(string queueName)" 336 "@brief Determines if a dispatcher queue exists\n\n" 337 "@param queueName String containing the name of queue\n" 338 "@ingroup Messaging") 339{ 340 return Dispatcher::isQueueRegistered(queueName); 341} 342 343DefineEngineFunction( registerMessageQueue, void, (const char *queueName), , "(string queueName)" 344 "@brief Registeres a dispatcher queue\n\n" 345 "@param queueName String containing the name of queue\n" 346 "@ingroup Messaging") 347{ 348 return Dispatcher::registerMessageQueue(queueName); 349} 350 351DefineEngineFunction( unregisterMessageQueue, void, (const char *queueName), , "(string queueName)" 352 "@brief Unregisters a dispatcher queue\n\n" 353 "@param queueName String containing the name of queue\n" 354 "@ingroup Messaging") 355{ 356 return Dispatcher::unregisterMessageQueue(queueName); 357} 358 359//----------------------------------------------------------------------------- 360 361DefineEngineFunction( registerMessageListener, bool, (const char *queueName, const char *listenerName), , "(string queueName, string listener)" 362 "@brief Registers an event message\n\n" 363 "@param queueName String containing the name of queue to attach listener to\n" 364 "@param listener Name of event messenger\n" 365 "@ingroup Messaging") 366{ 367 Dispatcher::IMessageListener *listener = dynamic_cast<Dispatcher::IMessageListener *>(Sim::findObject(listenerName)); 368 if(listener == NULL) 369 { 370 Con::errorf("registerMessageListener - Unable to find listener object, not an IMessageListener ?!"); 371 return false; 372 } 373 374 return Dispatcher::registerMessageListener(queueName, listener); 375} 376 377DefineEngineFunction( unregisterMessageListener, void, (const char *queueName, const char *listenerName), , "(string queueName, string listener)" 378 "@brief Unregisters an event message\n\n" 379 "@param queueName String containing the name of queue\n" 380 "@param listener Name of event messenger\n" 381 "@ingroup Messaging") 382{ 383 Dispatcher::IMessageListener *listener = dynamic_cast<Dispatcher::IMessageListener *>(Sim::findObject(listenerName)); 384 if(listener == NULL) 385 { 386 Con::errorf("unregisterMessageListener - Unable to find listener object, not an IMessageListener ?!"); 387 return; 388 } 389 390 Dispatcher::unregisterMessageListener(queueName, listener); 391} 392 393//----------------------------------------------------------------------------- 394 395DefineEngineFunction( dispatchMessage, bool, (const char *queueName, const char *message, const char *data), (""), "(string queueName, string message, string data)" 396 "@brief Dispatch a message to a queue\n\n" 397 "@param queueName Queue to dispatch the message to\n" 398 "@param message Message to dispatch\n" 399 "@param data Data for message\n" 400 "@return True for success, false for failure\n" 401 "@see dispatchMessageObject\n" 402 "@ingroup Messaging") 403{ 404 return Dispatcher::dispatchMessage(queueName, message, data); 405} 406 407DefineEngineFunction( dispatchMessageObject, bool, (const char *queueName, const char *message), ("", ""), "(string queueName, string message)" 408 "@brief Dispatch a message object to a queue\n\n" 409 "@param queueName Queue to dispatch the message to\n" 410 "@param message Message to dispatch\n" 411 "@return true for success, false for failure\n" 412 "@see dispatchMessage\n" 413 "@ingroup Messaging") 414{ 415 Message *msg = dynamic_cast<Message *>(Sim::findObject(message)); 416 if(msg == NULL) 417 { 418 Con::errorf("dispatchMessageObject - Unable to find message object"); 419 return false; 420 } 421 422 return Dispatcher::dispatchMessageObject(queueName, msg); 423} 424