source: nrEngine/include/EventManager.h @ 1

Revision 1, 9.5 KB checked in by art, 13 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#ifndef _NR_EVENTMANAGER_H_
15#define _NR_EVENTMANAGER_H_
16
17/*!
18 * \defgroup event Event-Management
19 *
20 * If you want to start to write a game you should be familar with event
21 * systems and event based programming. Event system are used to pass events
22 * between system modules without calling certain functions of that modules.
23 * So using of events could reduce the dependability of the system components.
24 *
25 * In our engine we are trying to improve the normal behaviour of the event
26 * management system. We do not only use simple events, instead of this we
27 * mix several techniques like signals, triggers and state machines within the concept
28 * of events to give the develeoper a possibility to increase the dependecy gap
29 * between application modules.
30 *
31 * The engine does also use name driven event system instead of id driven design.
32 * This is done for the reasons of readability and expandability. So if new
33 * event should be added to the system, it can be added by using other name rather
34 * then to recompile the application by adding new ids. Also using of string based
35 * names for the vents allows better using of scripting.
36 *
37 * New type of events could be easely added through plugins, so the engine must not be
38 * recompiled. For example: the engine could easely be extended to an input system.
39 * The input system can fully be programmed as a plugin. To allow a communication
40 * between the components of the engine and application, the new plugin could
41 * generate a new type of events, namely "input". Each event listener which is
42 * registered for hearing the communication channel for the input events will be
43 * informed if there is a new event.
44 *
45 * Our events are priority based. This means that each event does get a priority number
46 * defining how soon this event should be delivered. In each cycle the application
47 * running all events/messages comming to a channel will be collected in a priority queue.
48 * When the EventManager gets updated it tells the channels, that they now can deliver the
49 * messages to all connected actors. So the events with the highest priority will be
50 * delivered as first and the messages with the lowest priority will be delivered as last.
51 * If there is two events of the same priority, so it is not defined which one will be
52 * delivered as first.
53 *
54 * There is also special events having the priority number IMMEDIATE which will
55 * cause the channel to deliver this message immediately without be stored in the queue.
56 * This actors will be informed about this events as soon as the event is triggered.
57 *
58 * C++ does not provide any possibility to write the event management typesafe without
59 * big circumastances. There are some techniques, but this will end up in a big
60 * code plus a lot of function calls if to provide you the derived class instance instead
61 * of the base Event class. However we will try to give you the possibility of using
62 * your own event types derived from the base class in a controlled typesafe way.
63 * This means that if you handle correctly, so you will never cast to any wrong
64 * class by handling events.
65 *
66 * <hr>
67 * Another problem which we have to solve is: How to share event messages between
68 * plugins and application. Assume you compiled your application with the nrEngine
69 * library linked in. Then if you start the app you use the same memory mapping like
70 * the engine does. It means sending now events through the nrEngine's subsystem to
71 * your application is not a big problem. However if you now use plugins which are
72 * dynamic libraries, which are linked dynamicaly while your app is running, this
73 * approach could not work so easy. it means you are still able to send events, but
74 * you now can not convert an event to a type which is provided by the plugin.
75 * (i.e. plugin defines new type of events (NewEvent). Plugin create an instance of
76 * this class and send it to your application, you now not able to cast base class
77 * Event to this NewEvent class). Problem of sharing type information between modules.
78 *
79 * One solution were to forbidd plugins to send any new type of events which was
80 * not declared in the engine before. This solution might work, but then we loose
81 * to generality of our engine, because then we have to implement all things which
82 * are needed for properly use in the engine (graphics, inputs, ...)
83 *
84 * The other solution is to provide the engine TODO !!!!!!
85 **/
86
87//----------------------------------------------------------------------------------
88// Includes
89//----------------------------------------------------------------------------------
90#include "Prerequisities.h"
91#include "ITask.h"
92
93namespace nrEngine{
94
95
96        //! Main class providing the event messaging system
97        /**
98         * EventManager is a class managing the whole event communication
99         * system in our engine. The system can be thought as a message bus
100         * where all senders and recievers are connected to. They send/recieve
101         * messages through this bus. In the message bus we define message channels
102         * which suppose to send/recieve only events/messages of a certain type.
103         *
104         * \ingroup event
105        **/
106        class _NRExport EventManager: public ITask {
107                public:
108
109                        /**
110                         * Create a new event messaging channel. Any listener
111                         * connected to this channel will recieve only the messages
112                         * coming from senders connected to this channel. Any state change
113                         * of the channel will produce a new notice event to give the
114                         * listeners a possibility to react to the new state.
115                         *
116                         * @param name Unique name for this channel
117                         * @return either OK or an error code
118                         **/
119                        Result createChannel(const std::string& name);
120
121                        /**
122                         * Delete a certain communication channel.
123                         * All actors connected to the channel are getting disconnected
124                         * from the channel.
125                         *
126                         * @param name Unique name for the channel to remove
127                         **/
128                        Result removeChannel(const std::string& name);
129
130                        /**
131                         * Get a channel by its name
132                         * @return smart pointer to the channel
133                         **/
134                        SharedPtr<EventChannel> getChannel(const std::string& name);
135
136                        /**
137                         * Send a new event message to the channel. The priority number
138                         * of the event will be used to check if the message should be
139                         * send immediately or if it should go to the channel queue as first.
140                         *
141                         * @param name Unique channel name, where to emit the event (empty for all channels)
142                         * @param event SMart pointer on event to be emited
143                         **/
144                        Result emit(const std::string& name, SharedPtr<Event> event);
145
146                        /**
147                         * Same as emit() but this will emit messages to the system specific
148                         * default channel. This channel is used by the engine to establish
149                         * a communication between system components.
150                         *
151                         * NOTE: In next version this channel will be secured, so user are
152                         * not allowed to send messages here anymore
153                         **/
154                        Result emitSystem(SharedPtr<Event> event);
155
156                        /**
157                         * Inherited method from the ITask interface. Our event manager
158                         * is updated in each cycle to allow the channels to provide events
159                         * to all connected parties.
160                         **/
161                        Result updateTask();
162
163                        /**
164                         * Call this function if you prefer to create a new event object
165                         * from all registerd factories. The function will go through all
166                         * registered factories and ask them which does support the given
167                         * event type. If one could be found, so create it.
168                         **/
169                        SharedPtr<Event> createEvent(const std::string& eventType);
170
171                        /**
172                         * Register a new event factory. The given event factory will be
173                         * stored in a list. The factory can later be used to create instancies
174                         * of certain event types.
175                         *
176                         * @param name Unique name of a factory
177                         * @param factory Smart pointer containing the factory object
178                         **/
179                        Result registerFactory(const std::string& name, SharedPtr<EventFactory> factory);
180
181                        /**
182                         * Delete a registered factory from the list.
183                         **/
184                        Result removeFactory(const std::string& name);
185
186
187                private:
188
189                        //! Only engine is allowed to create the instance
190                        friend class Engine;
191
192                        /**
193                        * Create default system specific communication channel.
194                        * This channel will be used to allow communication between
195                        * system components.
196                        *
197                        * In the next version of nrEngine we should secure this channel
198                        * by flags, so user applications are not allowed to hear or to emit
199                        * messages in this channel!!!
200                        **/
201                        EventManager();
202
203                        //! Close all event channels and release used memory
204                        ~EventManager();
205
206                        //! Database representing the connection channels by their names
207                        typedef std::map<std::string, SharedPtr<EventChannel> > ChannelDatabase;
208
209                        //! Store the database in this variable
210                        ChannelDatabase mChannelDb;
211
212                        //! Here we do store event factories able to create new instancies
213                        typedef std::map<std::string, SharedPtr<EventFactory> > FactoryDatabase;
214
215                        //! Variable to hold the data
216                        FactoryDatabase mFactoryDb;
217
218        };
219
220}; // end namespace
221
222#endif
Note: See TracBrowser for help on using the repository browser.