Torque3D/Engine/source/util/messaging/eventManager.h
2014-09-21 22:50:47 +10:00

221 lines
6.9 KiB
C++

//-----------------------------------------------------------------------------
// Copyright (c) 2012 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.
//-----------------------------------------------------------------------------
#ifndef _EVENTMANAGER_H_
#define _EVENTMANAGER_H_
#ifndef _CONSOLE_H_
#include "console/console.h"
#endif
#ifndef _DISPATCHER_H_
#include "util/messaging/dispatcher.h"
#endif
#ifndef _TSIMPLEHASHTABLE_H
#include "core/tSimpleHashTable.h"
#endif
//-----------------------------------------------------------------------------
/// Listener class used by the EventManager to dispatch messages to specific
/// callbacks.
//-----------------------------------------------------------------------------
class EventManagerListener : public Dispatcher::IMessageListener
{
friend class EventManager;
/// Stores subscription information for a subscriber.
struct Subscriber
{
SimObjectPtr< SimObject > listener; ///< The listener object.
StringTableEntry callback; ///< The callback to execute when the event is triggered.
StringTableEntry event; ///< The event being listened for.
U32 callDepth;
bool removeFlag;
};
/// Subscriber table hashed by event name.
SimpleHashTable< Vector<Subscriber> > mSubscribers;
public:
// Ensure that the subscriber map doesn't use case-sensitive string comparisons.
EventManagerListener(): mSubscribers(64, false) {}
/// Called by the EventManager queue when an event is triggered. Calls all listeners subscribed to the triggered event.
virtual bool onMessageReceived( StringTableEntry queue, const char* event, const char* data );
virtual bool onMessageObjectReceived( StringTableEntry queue, Message *msg ) { return true; };
};
/// @addtogroup msgsys Message System
// @{
//-----------------------------------------------------------------------------
/// The EventManager class is a wrapper for the standard messaging system. It
/// provides functionality for management of event queues, events, and
/// subscriptions.
///
/// Creating an EventManager is as simple as calling <tt>new EventManager</tt>
/// and specifying a queue name.
///
/// Example Usage:
///
/// @code
/// // Create the EventManager.
/// $MyEventManager = new EventManager() { queue = "MyEventManager"; };
///
/// // Create an event.
/// $MyEventManager.registerEvent( "SomeCoolEvent" );
///
/// // Create a listener and subscribe.
/// $MyListener = new ScriptMsgListener() { class = MyListener; };
/// $MyEventManager.subscribe( $MyListener, "SomeCoolEvent" );
///
/// function MyListener::onSomeCoolEvent( %this, %data )
/// {
/// echo( "onSomeCoolEvent Triggered" );
/// }
///
/// // Trigger the event.
/// $MyEventManager.postEvent( "SomeCoolEvent", "Data" );
/// @endcode
//-----------------------------------------------------------------------------
class EventManager : public SimObject
{
typedef SimObject Parent;
private:
/// The name of the message queue.
StringTableEntry mQueue;
/// Registered events.
Vector<StringTableEntry> mEvents;
/// The event listener. Listens for all events and dispatches them to the appropriate subscribers.
EventManagerListener mListener;
/// List of all EventManagers.
static Vector<EventManager*> smEventManagers;
/// Sets the message queue.
static bool _setMessageQueue( void *obj, const char *index, const char *data )
{
static_cast<EventManager*>( obj )->setMessageQueue( data );
return false;
};
public:
DECLARE_CONOBJECT( EventManager );
EventManager();
virtual ~EventManager();
static void initPersistFields();
/// @name Properties
/// @{
StringTableEntry getMessageQueue() const { return mQueue; }
void setMessageQueue( const char* queue );
/// @}
/// @name Event Management
/// @{
/// Checks if an event is registered.
bool isRegisteredEvent( const char* eventName );
/// Registers an event.
bool registerEvent( const char* eventName );
/// Removes an event.
void unregisterEvent( const char* eventName );
/// Removes all events.
void unregisterAllEvents();
/// Triggers an event.
bool postEvent( const char* eventName, const char* data );
/// Adds a subscription to an event.
bool subscribe( SimObject *callbackObj, const char* event, const char* callback = NULL );
/// Remove a subscriber from an event.
void remove( SimObject *cbObj, const char* event );
void removeAll( SimObject *cbObj );
/// @}
/// @name Debug Output
/// @{
/// Prints all registered events to the console.
void dumpEvents();
/// Prints all subscribers to the console.
void dumpSubscribers();
/// Prints subscribers to a specific event to the console.
void dumpSubscribers( const char* event );
/// @}
/// @name Event Manager Tracking
/// @{
/// Adds an EventManager.
static void addEventManager( EventManager* em ) { smEventManagers.push_back( em ); };
/// Removes an EventManager.
static void removeEventManager( EventManager* em )
{
for( Vector<EventManager*>::iterator iter = smEventManagers.begin(); iter != smEventManagers.end(); iter++ )
{
if( *iter == em )
{
smEventManagers.erase_fast( iter );
break;
}
}
};
/// Retrieves an EventManager.
static EventManager* getEventManager( const char* name )
{
StringTableEntry queue = StringTable->insert( name );
for( Vector<EventManager*>::iterator iter = smEventManagers.begin(); iter != smEventManagers.end(); iter++ )
{
if( ( *iter )->mQueue == queue )
return *iter;
}
return NULL;
};
/// Prints all the EventManagers to the console.
static void printEventManagers()
{
for( Vector<EventManager*>::iterator iter = smEventManagers.begin(); iter != smEventManagers.end(); iter++ )
( *iter )->dumpSubscribers();
}
/// @}
};
// @}
#endif // _EVENTMANAGER_H_