source: nrEngine/include/EventChannel.h @ 19

Revision 19, 6.3 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_EVENT_CHANNEL_H_
15#define _NR_EVENT_CHANNEL_H_
16
17//----------------------------------------------------------------------------------
18// Includes
19//----------------------------------------------------------------------------------
20#include "Prerequisities.h"
21#include "EventActor.h"
22#include <queue>
23
24namespace nrEngine{
25
26        //! Event channel used for communication between application/engine's components
27        /**
28         * \par
29         * EventChannel represents a message bus for the communication between
30         * system components. Events/messages could be send through this channel
31         * to all listeners connected to this channel.
32         *
33         * \par
34         * In our engine we mix the concept of event messaging and state machines.
35         * So we do not have only events but also states. The states are stored in
36         * communication channels, so each listener of a channel could also be noticed
37         * if any state changes. This is also how we handle it in the nrEngine.
38         *
39         * \par
40         * The communication actors are connected to the channel by its name. Also
41         * the lifetime of each actor is tracked. So if an actor is removed from the
42         * memory, so it will be automaticaly disconnected from the database.
43         * We do not use smart pointers for this purpose, because it will cause in
44         * undefined working flow. i.e. if you think the actor is removed from the memory
45         * because you have deleted it, it still get noticed about the things going on
46         * the channel. So this will ends up in undefined state.In our implementation
47         * the destructor of EventActor does simply say all channels it connected to,
48         * that the object does not exists anymore, so it can be disconnected.
49         *
50         * \ingroup event
51        **/
52        class _NRExport EventChannel {
53                public:
54
55                        //! Create a new instance of the communication channel
56                        EventChannel(EventManager* manager, const std::string& name);
57
58                        //! Releas eused memory and destroy hte instance.
59                        virtual ~EventChannel();
60
61                        /**
62                         * Connect a new actor to the channel. The actor will be connected
63                         * so it get noticed about any communication on the channel.
64                         *
65                         * The actor has to implement default event reactions needed for
66                         * our channel communication system. Compilation error will occur
67                         * if the reactions to the default events are not implemented.
68                         *
69                         * @param actor An actor to connect to the channel
70                         * @param notice Should channel let notice the actor that he is connected now (default YES)
71                         **/
72                        Result add(EventActor* actor, bool notice = true);
73
74                        /**
75                         * Disconnect an actor from the channel. It is a good coding style
76                         * if you call this function, when you do not need the connection anymore.
77                         * However our engine does provide you the possibility to
78                         * forget about disconnecting the actors from the channel, because the lifetime
79                         * of an actor will be tracked. If the object does not exists anymore, so
80                         * it will be automaticaly disconnected.
81                         *
82                         * If you want to be performant, so remove actors from the channels, if they do not
83                         * need the connection anymore.
84                         *
85                         * @param actor An actor already connected to the channel
86                         * @param notice Should channel notice the actor, about disconnection (default YES)
87                         **/
88                        Result del(EventActor* actor, bool notice = true);
89
90                        /**
91                         * Get the name of the channel
92                         **/
93                        NR_FORCEINLINE const std::string& getName () const { return mName; }
94
95                        /**
96                         * Emit a certain event to a channel. This will send this event
97                         * to all connected actors, so they get noticed about new event.
98                         *
99                         * @param event Smart pointer to an event object
100                         **/
101                        void emit (SharedPtr<Event> event);
102
103                        /**
104                         * Instead of emit() this will not send the message directly to
105                         * the channel listeners, but it store the message first in
106                         * a queue based on priority numbers of the events. When
107                         * you call deliver(), then all messages are getting delivered
108                         * to the channel listeners
109                         *
110                         * @param event Smart pointer to the event message
111                         *
112                         * NOTE: If event priority is immediately so the message will
113                         *              be emitted immediately without be stored in the queue
114                         **/
115                        void push(SharedPtr<Event> event);
116
117                        /**
118                         * Deliver all stored event messages from the queue
119                         * to the actors connected to the channel.
120                         **/
121                        void deliver();
122                       
123                protected:
124                        //! The event manager system is a friend to this class
125                        friend class EventManager;
126
127                        //! Store here the mapping between actor names and their connections
128                        typedef std::map<std::string, EventActor*> ActorDatabase;
129
130                        //! Unique name of the communication channel
131                        std::string mName;
132                       
133                        //! We always does store a pointer to the event manager where this channel belongs to
134                        EventManager* mParentManager;
135
136                        //! Connected actor database
137                        ActorDatabase mActorDb;
138                         
139                        /**
140                         * This structure is used as a wrapper to define a way
141                         * how to distinguish between priority numbers of events.
142                         **/
143                        template <class ClassT>
144                        struct GreatEvent : public std::binary_function<ClassT, ClassT, bool>
145                        {
146                                bool operator()(ClassT x, ClassT y) const
147                                {
148                                        return x->getPriority() > y->getPriority();
149                                }
150                        };
151                       
152                        //! We store our event messages in a priority queue
153                        typedef std::priority_queue<SharedPtr<Event>, std::vector<SharedPtr<Event> >, GreatEvent<SharedPtr<Event> > > EventQueue;
154
155                        //! Store the event messages in this variable
156                        EventQueue mEventQueue;
157                       
158                        //! Check whenever a given actor is already connected
159                        bool isConnected(const std::string& name);
160                       
161                        //! Disconnect all actors from the channel
162                        void _disconnectAll();
163
164        };
165       
166}; // end namespace
167
168#endif
Note: See TracBrowser for help on using the repository browser.