e05fb5c7be79a21e47750b6451e9cf3dd2ceec0a
[senf.git] / PPI / Events.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.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 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief Events public header */
23
24 #ifndef HH_Events_
25 #define HH_Events_ 1
26
27 // Custom includes
28 #include <vector>
29 #include "Scheduler/ClockService.hh"
30 #include "predecl.hh"
31
32 //#include "Events.mpp"
33 ///////////////////////////////hh.p////////////////////////////////////////
34
35 namespace senf {
36 namespace ppi {
37     
38     /** \defgroup event_group Events
39
40         Events provide notification of events outside the PPI framework: I/O activity, Timers
41         etc. Events are very important since they drive the PPI: Without events, nothing will
42         happen.
43
44         \section event_impl Implementing Events
45
46         All events are derived from EventImplementation which is based on EventDescriptor.
47         \see EventImplementation
48      */
49
50     // Implementation: The concrete EventDescriptor implementation will need to set things up so
51     // some callback (within the EventDescriptor implementation) will be called when the event
52     // happens. This setup happens in 'v_enable()'. This internal handler sets up an EventType
53     // instance if needed and calls 'callback()'. 
54     //
55     // 'callback()' will access the EventBinding wrapper to find the user-callback to signal. It
56     // will do any needed internal processing, call that user callback and clean up afterwards.
57
58     /** \brief Generic event interface base-class
59
60         The EventDescriptor base-class provides an interface to control events.
61      */ 
62     class EventDescriptor
63     {
64     public:
65         virtual ~EventDescriptor();
66
67         bool enabled(); ///< Check, whether the event is currently enabled
68         void enabled(bool v); ///< Enable or disable the event
69
70     protected:
71         EventDescriptor();
72
73     private:
74         virtual void v_enable() = 0;    ///< Called to enable the event delivery
75         virtual void v_disable() = 0;   ///< Called to disable the event delivery
76
77         virtual bool v_isRegistered() = 0;
78
79         void notifyThrottle();
80         void notifyUnthrottle();
81
82         void registerRoute(ForwardingRoute & route);
83
84         bool enabled_;
85
86         typedef std::vector<ForwardingRoute*> Routes;
87         Routes routes_;
88
89         friend class ForwardingRoute;
90     };
91     
92     /** \brief Internal: Callback forwarders
93      */
94     template <class EventType, class Self>
95     class EventImplementationHelper
96     {
97     protected:
98         typedef typename detail::EventArgType<EventType>::type EventArg;
99
100         void callback(EventArg event, ClockService::clock_type time);
101                                         ///< Forward event to user callback
102                                         /**< \param[in] event Event argument to pass to the user
103                                              callback
104                                              \param[in] time Expected time of the event */
105         void callback(EventArg event);  ///< Forward event to user callback
106                                         /**< \param[in] event Event argument to pass to the user
107                                              callback. */
108
109     private:
110         detail::EventBinding<EventType> & binding();
111     };
112     
113 #ifndef DOXYGEN
114
115     template <class Self>
116     class EventImplementationHelper<void,Self>
117     {
118     protected:
119         void callback(ClockService::clock_type time);
120         void callback();
121
122     private:
123         detail::EventBinding<void> & binding();
124     };
125
126 #endif
127
128     /** \brief Event implementation base class
129
130         EventImplementation provides the base-class for all Event implementations. 
131         \code
132         class SomeEvent : public EventImplementation<SomeEventArg>
133         {
134         public:
135             SomeEvent() {}
136
137         private:
138             virtual void v_enable() {
139                 // register cb() to be called when the event occurs
140             }
141
142             virtual void v_disable() {
143                 // unregister cb()
144             }
145
146             void cb() {
147                 // Build event argument
148                 SomeEventArg arg (...); 
149                 // Call the event callback
150                 callback(arg);
151             }
152         };
153         \endcode
154
155         Every event needs to implement v_enable() and v_disable(). v_enable() should register some
156         member (in the example \c cb() ) to be called whenever the event occurs, while v_disable()
157         should unregister it.
158
159         The \a EventType argument to EventImplementation defines the type of argument passed to the
160         user callback. It defaults to \c void. . This user callback is called from within the
161         registered member (e.g. \c cb() ) by calling the inherited callback() member. This member
162         takes an \a EventType reference as argument which will be forwarded to the user callback. If
163         available, you should also provide the \e expected event time as a second argument.
164      */
165     template <class EventType>
166     class EventImplementation
167         : public EventDescriptor, 
168           public EventImplementationHelper< EventType, EventImplementation<EventType> >
169     {
170     public:
171         typedef EventType Event;
172         typedef typename detail::EventArgType<EventType>::type EventArg;
173
174         module::Module & module() const; ///< Module in which the event is registered
175         EventManager & manager() const; ///< EventManager of the event
176         
177     protected:
178         EventImplementation();
179
180     private:
181         virtual bool v_isRegistered();
182         void setBinding(detail::EventBinding<Event> & binding);
183
184         detail::EventBinding<Event> * binding_;
185
186         friend class EventManager;
187         friend class EventImplementationHelper< EventType, EventImplementation<EventType> >;
188     };
189
190 }}
191
192 ///////////////////////////////hh.e////////////////////////////////////////
193 #include "Events.cci"
194 //#include "Events.ct"
195 #include "Events.cti"
196 #endif
197
198 \f
199 // Local Variables:
200 // mode: c++
201 // fill-column: 100
202 // c-file-style: "senf"
203 // indent-tabs-mode: nil
204 // ispell-local-dictionary: "american"
205 // compile-command: "scons -u test"
206 // comment-column: 40
207 // End: