Torque3D Documentation / _generateds / eventManager.cpp

eventManager.cpp

Engine/source/util/messaging/eventManager.cpp

More...

Public Functions

ConsoleDocClass(EventManager , "@brief The <a href="/coding/class/classeventmanager/">EventManager</a> class is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> wrapper <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the standard messaging <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">system.\n\n</a>" "It provides functionality <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> management of event queues, events )
DefineEngineMethod(EventManager , dumpEvents , void , () , "()\n\n" "Print all registered events <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console." )
DefineEngineMethod(EventManager , dumpSubscribers , void , (const char *listenerName) , ("") , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Print all subscribers <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param event The event whose subscribers are <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be printed. If this parameter isn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> specified, all events will be dumped." )
DefineEngineMethod(EventManager , isRegisteredEvent , bool , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Check <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an event is registered or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">check.\n</a>" "@return Whether or not the event exists." )
DefineEngineMethod(EventManager , postEvent , bool , (const char *evt, const char *data) , ("") , "( String event, <a href="/coding/class/classstring/">String</a> data )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "~<a href="/coding/class/classtrigger/">Trigger</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">trigger.\n</a>" "@param data The data associated with the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@return Whether or not the event was dispatched successfully." )
DefineEngineMethod(EventManager , registerEvent , bool , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Register an event with the event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">manager.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">register.\n</a>" "@return Whether or not the event was registered successfully." )
DefineEngineMethod(EventManager , remove , void , (const char *listenerName, const char *evt) , "( SimObject listener, <a href="/coding/class/classstring/">String</a> event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Remove <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener from an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be removed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from.\n</a>" )
DefineEngineMethod(EventManager , removeAll , void , (const char *listenerName) , "( SimObject listener )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Remove <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener from all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )
DefineEngineMethod(EventManager , subscribe , bool , (const char *listenerName, const char *evt, const char *callback) , ("") , "( SimObject listener, <a href="/coding/class/classstring/">String</a> event, <a href="/coding/class/classstring/">String</a> callback )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Subscribe <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">subscribe.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> subscribe <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" "@param callback Optional method name <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive the event notification. If this is not specified, \"on\" will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">used.\n</a>" "@return Whether or not the subscription was successful." )
DefineEngineMethod(EventManager , unregisterEvent , void , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Remove an event from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">EventManager.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )

Detailed Description

Public Functions

ConsoleDocClass(EventManager , "@brief The <a href="/coding/class/classeventmanager/">EventManager</a> class is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> wrapper <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the standard messaging <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">system.\n\n</a>" "It provides functionality <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> management of event queues, events )

DefineEngineMethod(EventManager , dumpEvents , void , () , "()\n\n" "Print all registered events <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console." )

DefineEngineMethod(EventManager , dumpSubscribers , void , (const char *listenerName) , ("") , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Print all subscribers <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param event The event whose subscribers are <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be printed. If this parameter isn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> specified, all events will be dumped." )

DefineEngineMethod(EventManager , isRegisteredEvent , bool , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Check <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an event is registered or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">check.\n</a>" "@return Whether or not the event exists." )

DefineEngineMethod(EventManager , postEvent , bool , (const char *evt, const char *data) , ("") , "( String event, <a href="/coding/class/classstring/">String</a> data )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "~<a href="/coding/class/classtrigger/">Trigger</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">trigger.\n</a>" "@param data The data associated with the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@return Whether or not the event was dispatched successfully." )

DefineEngineMethod(EventManager , registerEvent , bool , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Register an event with the event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">manager.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">register.\n</a>" "@return Whether or not the event was registered successfully." )

DefineEngineMethod(EventManager , remove , void , (const char *listenerName, const char *evt) , "( SimObject listener, <a href="/coding/class/classstring/">String</a> event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Remove <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener from an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be removed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from.\n</a>" )

DefineEngineMethod(EventManager , removeAll , void , (const char *listenerName) , "( SimObject listener )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Remove <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener from all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )

DefineEngineMethod(EventManager , subscribe , bool , (const char *listenerName, const char *evt, const char *callback) , ("") , "( SimObject listener, <a href="/coding/class/classstring/">String</a> event, <a href="/coding/class/classstring/">String</a> callback )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Subscribe <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n</a>" "@param listener The listener <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">subscribe.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> subscribe <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" "@param callback Optional method name <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive the event notification. If this is not specified, \"on\" will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">used.\n</a>" "@return Whether or not the subscription was successful." )

DefineEngineMethod(EventManager , unregisterEvent , void , (const char *evt) , "( String event )\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "Remove an event from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">EventManager.\n</a>" "@param event The event <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )

IMPLEMENT_CONOBJECT(EventManager )

  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/eventManager.h"
 26
 27#include "console/engineAPI.h"
 28#include "console/consoleTypes.h"
 29#include "console/consoleInternal.h"
 30
 31IMPLEMENT_CONOBJECT( EventManager );
 32
 33ConsoleDocClass( EventManager,
 34   "@brief The EventManager class is a wrapper for the standard messaging system.\n\n"
 35
 36   "It provides functionality for management of event queues, events, and "
 37   "subscriptions. Creating an EventManager is as simple as calling new EventManager "
 38   "and specifying a queue name.\n\n"
 39
 40   "@tsexample\n"
 41  "// Create the EventManager.\n"
 42  "$MyEventManager = new EventManager() { queue = \"MyEventManager\"; };\n\n" 
 43  "// Create an event.\n" 
 44  "$MyEventManager.registerEvent( \"SomeCoolEvent\" );\n\n"  
 45  "// Create a listener and subscribe.\n" 
 46  "$MyListener = new ScriptMsgListener() { class = MyListener; };\n" 
 47  "$MyEventManager.subscribe( $MyListener, \"SomeCoolEvent\" );\n\n"  
 48  "function MyListener::onSomeCoolEvent( %this, %data )\n" 
 49  "{\n" 
 50  "     echo( \"onSomeCoolEvent Triggered\" );\n" 
 51  "}\n\n"  
 52  "// Trigger the event.\n" 
 53  "$MyEventManager.postEvent( \"SomeCoolEvent\", \"Data\" );\n" 
 54   "@endtsexample\n\n"
 55
 56   "@see ScriptMsgListener\n\n"
 57
 58   "@ingroup Messaging\n"
 59);
 60
 61Vector<EventManager*> EventManager::smEventManagers;
 62
 63//-----------------------------------------------------------------------------
 64/// Gets a list of all listeners of a specific event type and executes a
 65/// callback on each one.
 66/// 
 67/// @param event The name of the event that was triggered.
 68/// @param data The data associated with the event.
 69/// @return true to allow other listeners to receive the event, false otherwise
 70//-----------------------------------------------------------------------------
 71
 72// CodeReview [tom, 2/20/2007] There seemed to be a little confusion on the return value here.
 73// It is not a "successfully dispatched" value, it is used to prevent other
 74// listeners from receiving the message. Using the event manager this probably
 75// didn't matter since there was only one listener, however it would cause
 76// problems if more then one listener is registered with the queue.
 77bool EventManagerListener::onMessageReceived( StringTableEntry queue, const char* event, const char* data )
 78{
 79   Vector<Subscriber>* subscribers = mSubscribers.retreive( event );
 80   if( subscribers == NULL )
 81      return true;
 82
 83   for( Vector<Subscriber>::iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
 84   {
 85      if( iter->listener == NULL )
 86      {
 87         subscribers->erase_fast( iter -- );
 88         continue;
 89      }
 90
 91      if (!iter->removeFlag)
 92      {
 93         iter->callDepth++;
 94         Con::executef( iter->listener, iter->callback, data );
 95         iter->callDepth--;
 96         if (iter->removeFlag && iter->callDepth==0)
 97         {
 98            subscribers->erase_fast(iter--);
 99         }
100      }
101   }
102
103   return true;
104}
105
106//-----------------------------------------------------------------------------
107// Constructor
108//-----------------------------------------------------------------------------
109EventManager::EventManager() : mQueue( NULL )
110{
111   addEventManager( this );
112}
113
114//-----------------------------------------------------------------------------
115// Destructor
116//-----------------------------------------------------------------------------
117EventManager::~EventManager()
118{
119   setMessageQueue( "" );
120   unregisterAllEvents();
121   removeEventManager( this );
122}
123
124//-----------------------------------------------------------------------------
125// initPersistFields
126//-----------------------------------------------------------------------------
127void EventManager::initPersistFields()
128{
129   addProtectedField( "queue", TypeString, Offset( mQueue, EventManager ), &_setMessageQueue, &defaultProtectedGetFn, "List of events currently waiting" );
130}
131
132//-----------------------------------------------------------------------------
133/// Registers the message queue and listener with the messaging system.
134/// 
135/// @param queue The name of the queue. Set to "" to destroy the queue.
136//-----------------------------------------------------------------------------
137void EventManager::setMessageQueue( const char* queue )
138{
139   // If a queue is already registered, unregister it.
140   if( mQueue && Dispatcher::isQueueRegistered( mQueue ) )
141   {
142      unregisterAllEvents();
143      Dispatcher::unregisterMessageListener( mQueue, &mListener );
144      Dispatcher::unregisterMessageQueue( mQueue );
145   }
146
147   // Register the new queue.
148   if( queue && *queue )
149   {
150      Dispatcher::registerMessageQueue( queue );
151      Dispatcher::registerMessageListener( queue, &mListener );
152      mQueue = StringTable->insert( queue );
153   }
154}
155
156//-----------------------------------------------------------------------------
157/// Determines whether or not an event is registered with the EventManager.
158/// 
159/// @param event the event to check.
160//-----------------------------------------------------------------------------
161bool EventManager::isRegisteredEvent( const char* event )
162{
163   // Iterate over the event list.
164   StringTableEntry eventName = StringTable->insert( event );
165   for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
166   {
167      // Found.
168      if( *iter == eventName )
169         return true;
170   }
171
172   // Not found.
173   return false;
174}
175
176//-----------------------------------------------------------------------------
177/// Register an event with the EventManager.
178/// 
179/// @param event The event to register.
180/// @return Whether or not the event was successfully registered.
181//-----------------------------------------------------------------------------
182bool EventManager::registerEvent( const char* event )
183{
184   // Make sure the event has not been registered yet.
185   if( isRegisteredEvent( event ) )
186   {
187      Con::warnf( "EventManager::registerEvent - event %s already registered", event );
188      return false;
189   }
190
191   // Add to the event list.
192   mEvents.push_back( StringTable->insert( event ) );
193
194   // Create a list of subscribers for this event.
195   mListener.mSubscribers.insert( new Vector<EventManagerListener::Subscriber>, event );
196
197   return true;
198}
199
200//-----------------------------------------------------------------------------
201/// Removes all events from the EventManager.
202//-----------------------------------------------------------------------------
203void EventManager::unregisterAllEvents()
204{
205   // Iterate over all events.
206   for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
207   {
208      // Delete the subscriber list.
209      Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.remove( *iter );
210      if( subscribers )
211         delete subscribers;
212   }
213
214   // Clear the event list.
215   mEvents.clear();
216}
217
218//-----------------------------------------------------------------------------
219/// Removes an event from the EventManager.
220/// 
221/// @param event The event to remove.
222//-----------------------------------------------------------------------------
223void EventManager::unregisterEvent( const char* event )
224{
225   // If the event doesn't exist, we have succeeded in removing it!
226   if( !isRegisteredEvent( event ) )
227      return;
228
229   // Iterate over all events.
230   StringTableEntry eventName = StringTable->insert( event );
231   for( Vector<StringTableEntry>::iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
232   {
233      // Erase the event.
234      if( *iter == eventName )
235      {
236         mEvents.erase_fast( iter );
237         break;
238      }
239   }
240
241   // Delete the subscriber list.
242   Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.remove( event );
243   if( subscribers )
244      delete subscribers;
245}
246
247//-----------------------------------------------------------------------------
248/// Post an event to the EventManager's queue.
249/// 
250/// @param event The event to post.
251/// @param data Various data associated with the event.
252/// @return Whether or not the message was dispatched successfully.
253//-----------------------------------------------------------------------------
254bool EventManager::postEvent( const char* event, const char* data )
255{
256   AssertFatal( mQueue != NULL, "EventManager::postEvent - Queue not initialized" );
257   return Dispatcher::dispatchMessage( mQueue, event, data );
258}
259
260//-----------------------------------------------------------------------------
261/// Subscribe a listener to an event.
262/// 
263/// @param listener The listener to subscribe.
264/// @param event The event to subscribe to.
265/// @param callback Optional callback name to be called when the event is
266/// triggered.
267/// @return Whether or not the subscription was successful.
268//-----------------------------------------------------------------------------
269
270// CodeReview [tom, 2/20/2007] The "listener" argument was an IMessageListener,
271// but it was actually used as a SimObject and never a listener. Thus, it is now a SimObject.
272bool EventManager::subscribe(SimObject *callbackObj, const char* event, const char* callback /*= NULL */)
273{
274   // Make sure the event is valid.
275   if( !isRegisteredEvent( event ) )
276   {
277      Con::warnf( "EventManager::subscribe - %s is not a registered event.", event );
278      return false;
279   }
280
281   // Grab the callback name.
282   char* cb = NULL;
283   if( !callback || !*callback )
284   {
285      // Not specified, use default ( "onEvent" ).
286      S32 length = dStrlen( event ) + 5;
287      cb = new char[length];
288      dSprintf( cb, length, "on%s", event );
289   }
290   else
291   {
292      dsize_t cbLen = dStrlen(callback) + 1;
293      cb = new char[cbLen];
294      dStrcpy(cb, callback, cbLen);
295   }
296
297   // Create the subscriber object.
298   EventManagerListener::Subscriber subscriber;
299   subscriber.listener = callbackObj;
300   subscriber.event = StringTable->insert( event );
301   subscriber.callback = StringTable->insert( cb );
302   subscriber.callDepth = 0;
303   subscriber.removeFlag = false;
304
305   delete [] cb;
306
307   // Grab the subscriber list.
308   Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retreive( event );
309
310   // If the event exists, there should always be a valid subscriber list.
311   AssertFatal( subscribers, "Invalid event subscriber list." );
312
313   // Add the subscriber.
314   subscribers->push_back( subscriber );
315
316   return true;
317}
318
319
320//-----------------------------------------------------------------------------
321/// remove a listener from an event.
322/// 
323/// @param listener The listener to remove from an event callback list.
324/// @param event The event to remove the listener from.
325//-----------------------------------------------------------------------------
326
327// CodeReview [tom, 2/20/2007] The "listener" argument was an IMessageListener,
328// but it was actually used as a SimObject and never a listener. Thus, it is now a SimObject.
329void EventManager::remove(SimObject *cbObj, const char* event)
330{
331   // If the event doesn't exist, we have succeeded in removing it!
332   if( !isRegisteredEvent( event ) )
333      return;
334
335   Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retreive( event );
336   if( !subscribers )
337      return;
338
339   for( Vector<EventManagerListener::Subscriber>::iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
340   {
341      // Erase the event.
342      if( iter->listener == cbObj )
343      {
344        if (iter->callDepth > 0)
345           iter->removeFlag = true;
346        else
347           subscribers->erase_fast( iter );
348         break;
349      }
350   }
351}
352
353void EventManager::removeAll(SimObject *cbObj)
354{
355   // Iterate over all events.
356   for( Vector<StringTableEntry>::const_iterator iter1 = mEvents.begin(); iter1 != mEvents.end(); iter1++ )
357   {
358      Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retreive( *iter1 );
359      if( !subscribers )
360        continue;
361      for( Vector<EventManagerListener::Subscriber>::iterator iter2 = subscribers->begin(); iter2 != subscribers->end(); iter2++ )
362      {
363        // Erase the event.
364        if( iter2->listener == cbObj )
365        {
366           if (iter2->callDepth > 0)
367              iter2->removeFlag = true;
368           else
369              subscribers->erase_fast( iter2 );
370          break;
371        }
372      }
373   }
374
375}
376//-----------------------------------------------------------------------------
377/// Print all registered events to the console.
378//-----------------------------------------------------------------------------
379void EventManager::dumpEvents()
380{
381   Con::printf( "%s Events", mQueue );
382   for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
383      Con::printf( "   %s", *iter );
384}
385
386//-----------------------------------------------------------------------------
387/// Print the subscribers to an event.
388/// 
389/// @param event The event whose subscribers are to be printed.
390//-----------------------------------------------------------------------------
391void EventManager::dumpSubscribers( const char* event )
392{
393   Vector<EventManagerListener::Subscriber>* subscribers = mListener.mSubscribers.retreive( event );
394   if( !subscribers )
395   {
396      Con::warnf( "EventManager::dumpSubscriber - %s is not a valid event.", event );
397      return;
398   }
399
400   Con::printf( "%s Subscribers", event );
401   for( Vector<EventManagerListener::Subscriber>::const_iterator iter = subscribers->begin(); iter != subscribers->end(); iter++ )
402      if( iter->listener )
403      {
404         // Grab the best fit name. This should be the first found of name, class, superclass, or class type.
405         Namespace* ns = iter->listener->getNamespace();
406         const char* name = ns ? ns->mName : getClassName() ;
407         Con::printf( "   %s -> %s", name, iter->callback );
408      }
409}
410
411//-----------------------------------------------------------------------------
412/// Print all registered events and their subscribers to the console.
413//-----------------------------------------------------------------------------
414void EventManager::dumpSubscribers()
415{
416   Con::printf( "%s Events", mQueue );
417   for( Vector<StringTableEntry>::const_iterator iter = mEvents.begin(); iter != mEvents.end(); iter++ )
418      dumpSubscribers( *iter );
419}
420
421//-----------------------------------------------------------------------------
422// Console Methods
423//-----------------------------------------------------------------------------
424DefineEngineMethod( EventManager, registerEvent, bool, ( const char * evt ), , "( String event )\n"
425              "Register an event with the event manager.\n"
426              "@param event The event to register.\n"
427              "@return Whether or not the event was registered successfully." )
428{
429   return object->registerEvent( evt );
430}
431
432DefineEngineMethod( EventManager, unregisterEvent, void, ( const char * evt ), , "( String event )\n"
433              "Remove an event from the EventManager.\n"
434              "@param event The event to remove.\n" )
435{
436   object->unregisterEvent( evt );
437}
438
439DefineEngineMethod( EventManager, isRegisteredEvent, bool, ( const char * evt ), , "( String event )\n"
440              "Check if an event is registered or not.\n"
441              "@param event The event to check.\n"
442              "@return Whether or not the event exists." )
443{
444   return object->isRegisteredEvent( evt );
445}
446
447DefineEngineMethod( EventManager, postEvent, bool, ( const char * evt, const char * data ), (""), "( String event, String data )\n"
448              "~Trigger an event.\n"
449              "@param event The event to trigger.\n"
450              "@param data The data associated with the event.\n"
451              "@return Whether or not the event was dispatched successfully." )
452{
453   if( !object->getMessageQueue() || !object->getMessageQueue()[ 0 ] )
454   {
455      Con::errorf( "EventManager::postEvent - No queue name set on EventManager" );
456      return false;
457   }
458
459   return object->postEvent( evt, data );
460}
461
462DefineEngineMethod( EventManager, subscribe, bool, ( const char * listenerName, const char * evt, const char * callback ), (""), "( SimObject listener, String event, String callback )\n\n"
463              "Subscribe a listener to an event.\n"
464              "@param listener The listener to subscribe.\n"
465              "@param event The event to subscribe to.\n"
466              "@param callback Optional method name to receive the event notification. If this is not specified, \"on[event]\" will be used.\n"
467              "@return Whether or not the subscription was successful." )
468{
469   // Find the listener object.
470   SimObject *cbObj = dynamic_cast<SimObject *>(Sim::findObject(listenerName));
471   if( cbObj == NULL )
472   {
473      Con::warnf( "EventManager::subscribe - Invalid listener." );
474      return false;
475   }
476
477   return object->subscribe( cbObj, evt, callback );
478}
479
480DefineEngineMethod( EventManager, remove, void, ( const char * listenerName, const char * evt), , "( SimObject listener, String event )\n\n"
481              "Remove a listener from an event.\n"
482              "@param listener The listener to remove.\n"
483              "@param event The event to be removed from.\n")
484{
485   // Find the listener object.
486   SimObject * listener = dynamic_cast< SimObject * >( Sim::findObject( listenerName ) );
487   if( listener )
488      object->remove( listener, evt );
489}
490
491DefineEngineMethod( EventManager, removeAll, void, ( const char * listenerName ), , "( SimObject listener )\n\n"
492              "Remove a listener from all events.\n"
493              "@param listener The listener to remove.\n")
494{
495   // Find the listener object.
496
497   SimObject * listener = dynamic_cast< SimObject * >( Sim::findObject( listenerName ) );
498   if( listener )
499      object->removeAll( listener );
500}
501
502DefineEngineMethod( EventManager, dumpEvents, void, (), , "()\n\n"
503              "Print all registered events to the console." )
504{
505   object->dumpEvents();
506}
507
508DefineEngineMethod( EventManager, dumpSubscribers, void, ( const char * listenerName ), (""), "( String event )\n\n"
509              "Print all subscribers to an event to the console.\n"
510              "@param event The event whose subscribers are to be printed. If this parameter isn't specified, all events will be dumped." )
511{
512   if (String::compare(listenerName, "") != 0)
513      object->dumpSubscribers( listenerName );
514   else
515      object->dumpSubscribers();
516}
517