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