eventManager.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "messaging/eventManager.h"
  23. #include "console/consoleTypes.h"
  24. #include "console/consoleInternal.h"
  25. #include "eventManager_ScriptBinding.h"
  26. IMPLEMENT_CONOBJECT( EventManager );
  27. Vector<EventManager*> EventManager::smEventManagers;
  28. //-----------------------------------------------------------------------------
  29. /// Gets a list of all listeners of a specific event type and executes a
  30. /// callback on each one.
  31. ///
  32. /// @param event The name of the event that was triggered.
  33. /// @param data The data associated with the event.
  34. /// @return true to allow other listeners to receive the event, false otherwise
  35. //-----------------------------------------------------------------------------
  36. // CodeReview [tom, 2/20/2007] There seemed to be a little confusion on the return value here.
  37. // It is not a "successfully dispatched" value, it is used to prevent other
  38. // listeners from receiving the message. Using the event manager this probably
  39. // didn't matter since there was only one listener, however it would cause
  40. // problems if more then one listener is registered with the queue.
  41. bool EventManagerListener::onMessageReceived( StringTableEntry queue, const char* event, const char* data )
  42. {
  43. Vector<Subscriber>* subscribers = mSubscribers.retrieve( event );
  44. if( subscribers == NULL )
  45. return true;
  46. for( Vector<Subscriber>::const_iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
  47. {
  48. // If we returned a string that is not "", try to convert it to true/false
  49. const char* conResult = Con::executef( iter->listener, 2, iter->callback, data );
  50. if( dStrcmp( conResult, "" ) != 0 && dAtob( conResult ) == false )
  51. return false;
  52. }
  53. return true;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Constructor
  57. //-----------------------------------------------------------------------------
  58. EventManager::EventManager() : mQueue( NULL )
  59. {
  60. addEventManager( this );
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Destructor
  64. //-----------------------------------------------------------------------------
  65. EventManager::~EventManager()
  66. {
  67. setMessageQueue( "" );
  68. unregisterAllEvents();
  69. removeEventManager( this );
  70. }
  71. //-----------------------------------------------------------------------------
  72. // initPersistFields
  73. //-----------------------------------------------------------------------------
  74. void EventManager::initPersistFields()
  75. {
  76. addProtectedField( "queue", TypeString, Offset( mQueue, EventManager ), &setMessageQueue, &defaultProtectedGetFn, "" );
  77. }
  78. //-----------------------------------------------------------------------------
  79. /// Registers the message queue and listener with the messaging system.
  80. ///
  81. /// @param queue The name of the queue. Set to "" to destroy the queue.
  82. //-----------------------------------------------------------------------------
  83. void EventManager::setMessageQueue( const char* queue )
  84. {
  85. // If a queue is already registered, unregister it.
  86. if( mQueue && Dispatcher::isQueueRegistered( mQueue ) )
  87. {
  88. unregisterAllEvents();
  89. Dispatcher::unregisterMessageListener( mQueue, &mListener );
  90. Dispatcher::unregisterMessageQueue( mQueue );
  91. }
  92. // Register the new queue.
  93. if( queue && *queue )
  94. {
  95. Dispatcher::registerMessageQueue( queue );
  96. Dispatcher::registerMessageListener( queue, &mListener );
  97. mQueue = StringTable->insert( queue );
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. /// Determines whether or not an event is registered with the EventManager.
  102. ///
  103. /// @param event the event to check.
  104. //-----------------------------------------------------------------------------
  105. bool EventManager::isRegisteredEvent( const char* event )
  106. {
  107. // Iterate over the event list.
  108. StringTableEntry eventName = StringTable->insert( event );
  109. for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
  110. {
  111. // Found.
  112. if( *iter == eventName )
  113. return true;
  114. }
  115. // Not found.
  116. return false;
  117. }
  118. //-----------------------------------------------------------------------------
  119. /// Register an event with the EventManager.
  120. ///
  121. /// @param event The event to register.
  122. /// @return Whether or not the event was successfully registered.
  123. //-----------------------------------------------------------------------------
  124. bool EventManager::registerEvent( const char* event )
  125. {
  126. // Make sure the event has not been registered yet.
  127. if( isRegisteredEvent( event ) )
  128. {
  129. Con::warnf( "EventManager::registerEvent - event %s already registered", event );
  130. return false;
  131. }
  132. // Add to the event list.
  133. mEvents.push_back( StringTable->insert( event ) );
  134. // Create a list of subscribers for this event.
  135. mListener.mSubscribers.insert( new Vector<EventManagerListener::Subscriber>, event );
  136. return true;
  137. }
  138. //-----------------------------------------------------------------------------
  139. /// Removes all events from the EventManager.
  140. //-----------------------------------------------------------------------------
  141. void EventManager::unregisterAllEvents()
  142. {
  143. // Iterate over all events.
  144. for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
  145. {
  146. // Delete the subscriber list.
  147. Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.remove( *iter );
  148. if( subscribers )
  149. delete subscribers;
  150. }
  151. // Clear the event list.
  152. mEvents.clear();
  153. }
  154. //-----------------------------------------------------------------------------
  155. /// Removes an event from the EventManager.
  156. ///
  157. /// @param event The event to remove.
  158. //-----------------------------------------------------------------------------
  159. void EventManager::unregisterEvent( const char* event )
  160. {
  161. // If the event doesn't exist, we have succeeded in removing it!
  162. if( !isRegisteredEvent( event ) )
  163. return;
  164. // Iterate over all events.
  165. StringTableEntry eventName = StringTable->insert( event );
  166. for( Vector<StringTableEntry>::iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
  167. {
  168. // Erase the event.
  169. if( *iter == eventName )
  170. {
  171. mEvents.erase_fast( iter );
  172. break;
  173. }
  174. }
  175. // Delete the subscriber list.
  176. Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.remove( event );
  177. if( subscribers )
  178. delete subscribers;
  179. }
  180. //-----------------------------------------------------------------------------
  181. /// Post an event to the EventManager's queue.
  182. ///
  183. /// @param event The event to post.
  184. /// @param data Various data associated with the event.
  185. /// @return Whether or not the message was dispatched successfully.
  186. //-----------------------------------------------------------------------------
  187. bool EventManager::postEvent( const char* event, const char* data )
  188. {
  189. return Dispatcher::dispatchMessage( mQueue, event, data );
  190. }
  191. //-----------------------------------------------------------------------------
  192. /// Subscribe a listener to an event.
  193. ///
  194. /// @param listener The listener to subscribe.
  195. /// @param event The event to subscribe to.
  196. /// @param callback Optional callback name to be called when the event is
  197. /// triggered.
  198. /// @return Whether or not the subscription was successful.
  199. //-----------------------------------------------------------------------------
  200. // CodeReview [tom, 2/20/2007] The "listener" argument was an IMessageListener,
  201. // but it was actually used as a SimObject and never a listener. Thus, it is now a SimObject.
  202. bool EventManager::subscribe(SimObject *callbackObj, const char* event, const char* callback /*= NULL */)
  203. {
  204. // Make sure the event is valid.
  205. if( !isRegisteredEvent( event ) )
  206. {
  207. Con::warnf( "EventManager::subscribe - %s is not a registered event.", event );
  208. return false;
  209. }
  210. // Grab the callback name.
  211. char* cb = NULL;
  212. if( !callback || !*callback )
  213. {
  214. // Not specified, use default ( "onEvent" ).
  215. S32 length = dStrlen( event ) + 5;
  216. cb = new char[length];
  217. dSprintf( cb, length, "on%s", event );
  218. }
  219. else
  220. {
  221. cb = new char[dStrlen(callback) + 1];
  222. dStrcpy(cb, callback);
  223. }
  224. // Create the subscriber object.
  225. EventManagerListener::Subscriber subscriber;
  226. subscriber.listener = callbackObj;
  227. subscriber.event = StringTable->insert( event );
  228. subscriber.callback = StringTable->insert( cb );
  229. delete [] cb;
  230. // Grab the subscriber list.
  231. Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retrieve( event );
  232. // If the event exists, there should always be a valid subscriber list.
  233. AssertFatal( subscribers, "Invalid event subscriber list." );
  234. // Add the subscriber.
  235. subscribers->push_back( subscriber );
  236. return true;
  237. }
  238. //-----------------------------------------------------------------------------
  239. /// remove a listener from an event.
  240. ///
  241. /// @param listener The listener to remove from an event callback list.
  242. /// @param event The event to remove the listener from.
  243. //-----------------------------------------------------------------------------
  244. // CodeReview [tom, 2/20/2007] The "listener" argument was an IMessageListener,
  245. // but it was actually used as a SimObject and never a listener. Thus, it is now a SimObject.
  246. void EventManager::remove(SimObject *cbObj, const char* event)
  247. {
  248. // If the event doesn't exist, we have succeeded in removing it!
  249. if( !isRegisteredEvent( event ) )
  250. return;
  251. Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retrieve( event );
  252. if( !subscribers )
  253. return;
  254. for( Vector<EventManagerListener::Subscriber>::iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
  255. {
  256. // Erase the event.
  257. if( iter->listener == cbObj )
  258. {
  259. subscribers->erase_fast( iter );
  260. break;
  261. }
  262. }
  263. }
  264. //-----------------------------------------------------------------------------
  265. /// Print all registered events to the console.
  266. //-----------------------------------------------------------------------------
  267. void EventManager::dumpEvents()
  268. {
  269. Con::printf( "%s Events", mQueue );
  270. for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
  271. Con::printf( " %s", *iter );
  272. }
  273. //-----------------------------------------------------------------------------
  274. /// Print the subscribers to an event.
  275. ///
  276. /// @param event The event whose subscribers are to be printed.
  277. //-----------------------------------------------------------------------------
  278. void EventManager::dumpSubscribers( const char* event )
  279. {
  280. Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retrieve( event );
  281. if( !subscribers )
  282. {
  283. Con::warnf( "EventManager::dumpSubscriber - %s is not a valid event.", event );
  284. return;
  285. }
  286. Con::printf( "%s Subscribers", event );
  287. for( Vector<EventManagerListener::Subscriber>::const_iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
  288. {
  289. // Grab the best fit name. This should be the first found of name, class, superclass, or class type.
  290. Namespace* ns = iter->listener->getNamespace();
  291. const char* name = ns ? ns->mName : getClassName() ;
  292. Con::printf( " %s -> %s", name, iter->callback );
  293. }
  294. }
  295. //-----------------------------------------------------------------------------
  296. /// Print all registered events and their subscribers to the console.
  297. //-----------------------------------------------------------------------------
  298. void EventManager::dumpSubscribers()
  299. {
  300. Con::printf( "%s Events", mQueue );
  301. for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
  302. dumpSubscribers( *iter );
  303. }