EventManager.h

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 
00014 #ifndef _NR_EVENTMANAGER_H_
00015 #define _NR_EVENTMANAGER_H_
00016 
00017 /*!
00018  * \defgroup event Event-Management
00019  *
00020  * If you want to start to write a game you should be familar with event
00021  * systems and event based programming. Event system are used to pass events
00022  * between system modules without calling certain functions of that modules.
00023  * So using of events could reduce the dependability of the system components.
00024  *
00025  * In our engine we are trying to improve the normal behaviour of the event
00026  * management system. We do not only use simple events, instead of this we
00027  * mix several techniques like signals, triggers and state machines within the concept
00028  * of events to give the develeoper a possibility to increase the dependecy gap
00029  * between application modules.
00030  *
00031  * The engine does also use name driven event system instead of id driven design.
00032  * This is done for the reasons of readability and expandability. So if new
00033  * event should be added to the system, it can be added by using other name rather
00034  * then to recompile the application by adding new ids. Also using of string based
00035  * names for the vents allows better using of scripting.
00036  *
00037  * New type of events could be easely added through plugins, so the engine must not be
00038  * recompiled. For example: the engine could easely be extended to an input system.
00039  * The input system can fully be programmed as a plugin. To allow a communication
00040  * between the components of the engine and application, the new plugin could
00041  * generate a new type of events, namely "input". Each event listener which is
00042  * registered for hearing the communication channel for the input events will be
00043  * informed if there is a new event.
00044  *
00045  * Our events are priority based. This means that each event does get a priority number
00046  * defining how soon this event should be delivered. In each cycle the application
00047  * running all events/messages comming to a channel will be collected in a priority queue.
00048  * When the EventManager gets updated it tells the channels, that they now can deliver the
00049  * messages to all connected actors. So the events with the highest priority will be
00050  * delivered as first and the messages with the lowest priority will be delivered as last.
00051  * If there is two events of the same priority, so it is not defined which one will be
00052  * delivered as first.
00053  *
00054  * There is also special events having the priority number IMMEDIATE which will
00055  * cause the channel to deliver this message immediately without be stored in the queue.
00056  * This actors will be informed about this events as soon as the event is triggered.
00057  *
00058  * C++ does not provide any possibility to write the event management typesafe without
00059  * big circumastances. There are some techniques, but this will end up in a big
00060  * code plus a lot of function calls if to provide you the derived class instance instead
00061  * of the base Event class. However we will try to give you the possibility of using
00062  * your own event types derived from the base class in a controlled typesafe way.
00063  * This means that if you handle correctly, so you will never cast to any wrong
00064  * class by handling events.
00065  *
00066  * <hr>
00067  * Another problem which we have to solve is: How to share event messages between
00068  * plugins and application. Assume you compiled your application with the nrEngine
00069  * library linked in. Then if you start the app you use the same memory mapping like
00070  * the engine does. It means sending now events through the nrEngine's subsystem to
00071  * your application is not a big problem. However if you now use plugins which are
00072  * dynamic libraries, which are linked dynamicaly while your app is running, this
00073  * approach could not work so easy. it means you are still able to send events, but
00074  * you now can not convert an event to a type which is provided by the plugin.
00075  * (i.e. plugin defines new type of events (NewEvent). Plugin create an instance of
00076  * this class and send it to your application, you now not able to cast base class
00077  * Event to this NewEvent class). Problem of sharing type information between modules.
00078  *
00079  * One solution were to forbidd plugins to send any new type of events which was
00080  * not declared in the engine before. This solution might work, but then we loose
00081  * to generality of our engine, because then we have to implement all things which
00082  * are needed for properly use in the engine (graphics, inputs, ...)
00083  *
00084  * The other solution is to provide the engine TODO !!!!!!
00085  **/
00086 
00087 //----------------------------------------------------------------------------------
00088 // Includes
00089 //----------------------------------------------------------------------------------
00090 #include "Prerequisities.h"
00091 #include "ITask.h"
00092 
00093 namespace nrEngine{
00094 
00095 
00096         //! Main class providing the event messaging system
00097         /**
00098          * EventManager is a class managing the whole event communication
00099          * system in our engine. The system can be thought as a message bus
00100          * where all senders and recievers are connected to. They send/recieve
00101          * messages through this bus. In the message bus we define message channels
00102          * which suppose to send/recieve only events/messages of a certain type.
00103          *
00104          * \ingroup event
00105         **/
00106         class _NRExport EventManager: public ITask {
00107                 public:
00108 
00109                         /**
00110                          * Create a new event messaging channel. Any listener
00111                          * connected to this channel will recieve only the messages
00112                          * coming from senders connected to this channel. Any state change
00113                          * of the channel will produce a new notice event to give the
00114                          * listeners a possibility to react to the new state.
00115                          *
00116                          * @param name Unique name for this channel
00117                          * @return either OK or an error code
00118                          **/
00119                         Result createChannel(const std::string& name);
00120 
00121                         /**
00122                          * Delete a certain communication channel.
00123                          * All actors connected to the channel are getting disconnected
00124                          * from the channel.
00125                          *
00126                          * @param name Unique name for the channel to remove
00127                          **/
00128                         Result removeChannel(const std::string& name);
00129 
00130                         /**
00131                          * Get a channel by its name
00132                          * @return smart pointer to the channel
00133                          **/
00134                         SharedPtr<EventChannel> getChannel(const std::string& name);
00135 
00136                         /**
00137                          * Send a new event message to the channel. The priority number
00138                          * of the event will be used to check if the message should be
00139                          * send immediately or if it should go to the channel queue as first.
00140                          *
00141                          * @param name Unique channel name, where to emit the event (empty for all channels)
00142                          * @param event SMart pointer on event to be emited
00143                          **/
00144                         Result emit(const std::string& name, SharedPtr<Event> event);
00145 
00146                         /**
00147                          * Same as emit() but this will emit messages to the system specific
00148                          * default channel. This channel is used by the engine to establish
00149                          * a communication between system components.
00150                          *
00151                          * NOTE: In next version this channel will be secured, so user are
00152                          * not allowed to send messages here anymore
00153                          **/
00154                         Result emitSystem(SharedPtr<Event> event);
00155 
00156                         /**
00157                          * Inherited method from the ITask interface. Our event manager
00158                          * is updated in each cycle to allow the channels to provide events
00159                          * to all connected parties.
00160                          **/
00161                         Result updateTask();
00162 
00163                         /**
00164                          * Call this function if you prefer to create a new event object
00165                          * from all registerd factories. The function will go through all
00166                          * registered factories and ask them which does support the given
00167                          * event type. If one could be found, so create it.
00168                          **/
00169                         SharedPtr<Event> createEvent(const std::string& eventType);
00170 
00171                         /**
00172                          * Register a new event factory. The given event factory will be
00173                          * stored in a list. The factory can later be used to create instancies
00174                          * of certain event types.
00175                          *
00176                          * @param name Unique name of a factory
00177                          * @param factory Smart pointer containing the factory object
00178                          **/
00179                         Result registerFactory(const std::string& name, SharedPtr<EventFactory> factory);
00180 
00181                         /**
00182                          * Delete a registered factory from the list.
00183                          **/
00184                         Result removeFactory(const std::string& name);
00185 
00186                         #if 0
00187                         /**
00188                          * Create and emit a message through a channel.
00189                          * @param channel Channel name where to emit 
00190                          * @return Result of emit() method
00191                          **/
00192                         template<class EventT>
00193                         Result createEmit(const std::string& channel, void* param = NULL)
00194                         {
00195                                 SharedPtr<Event> msg(new EventT);
00196                                 return emit(channel, msg);
00197                         }
00198                         #endif
00199                         
00200                 private:
00201 
00202                         //! Only engine is allowed to create the instance
00203                         friend class Engine;
00204 
00205                         /**
00206                         * Create default system specific communication channel.
00207                         * This channel will be used to allow communication between
00208                         * system components.
00209                         *
00210                         * In the next version of nrEngine we should secure this channel
00211                         * by flags, so user applications are not allowed to hear or to emit
00212                         * messages in this channel!!!
00213                         **/
00214                         EventManager();
00215 
00216                         //! Close all event channels and release used memory
00217                         ~EventManager();
00218 
00219                         //! Database representing the connection channels by their names
00220                         typedef std::map<std::string, SharedPtr<EventChannel> > ChannelDatabase;
00221 
00222                         //! Store the database in this variable
00223                         ChannelDatabase mChannelDb;
00224 
00225                         //! Here we do store event factories able to create new instancies
00226                         typedef std::map<std::string, SharedPtr<EventFactory> > FactoryDatabase;
00227 
00228                         //! Variable to hold the data
00229                         FactoryDatabase mFactoryDb;
00230 
00231         };
00232 
00233 }; // end namespace
00234 
00235 #endif

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1