PPI: Rename all 'Reader's to 'Source's and 'Writer's to 'Sink's
[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 \n
48             \ref ppi_events        
49      */
50
51     // Implementation: The concrete EventDescriptor implementation will need to set things up so
52     // some callback (within the EventDescriptor implementation) will be called when the event
53     // happens. This setup happens in 'v_enable()'. This internal handler sets up an EventType
54     // instance if needed and calls 'callback()'. 
55     //
56     // 'callback()' will access the EventBinding wrapper to find the user-callback to signal. It
57     // will do any needed internal processing, call that user callback and clean up afterwards.
58
59     /** \brief Generic event interface base-class
60
61         The EventDescriptor base-class provides an interface to control events.
62
63         \see \ref ppi_events
64      */ 
65     class EventDescriptor
66     {
67     public:
68         virtual ~EventDescriptor();
69
70         bool enabled(); ///< Check, whether the event is currently enabled
71         void enabled(bool v); ///< Enable or disable the event
72
73     protected:
74         EventDescriptor();
75
76     private:
77         virtual void v_enable() = 0;    ///< Called to enable the event delivery
78         virtual void v_disable() = 0;   ///< Called to disable the event delivery
79
80         virtual bool v_isRegistered() = 0;
81
82         void notifyThrottle();
83         void notifyUnthrottle();
84
85         void registerRoute(ForwardingRoute & route);
86
87         bool enabled_;
88
89         typedef std::vector<ForwardingRoute*> Routes;
90         Routes routes_;
91
92         friend class ForwardingRoute;
93     };
94     
95     /** \brief Internal: Callback forwarders
96      */
97     template <class EventType, class Self>
98     class EventImplementationHelper
99     {
100     protected:
101         typedef typename detail::EventArgType<EventType>::type EventArg;
102
103         void callback(EventArg event, ClockService::clock_type time);
104                                         ///< Forward event to user callback
105                                         /**< \param[in] event Event argument to pass to the user
106                                              callback
107                                              \param[in] time Expected time of the event */
108         void callback(EventArg event);  ///< Forward event to user callback
109                                         /**< \param[in] event Event argument to pass to the user
110                                              callback. */
111
112     private:
113         detail::EventBinding<EventType> & binding();
114     };
115     
116 #ifndef DOXYGEN
117
118     template <class Self>
119     class EventImplementationHelper<void,Self>
120     {
121     protected:
122         void callback(ClockService::clock_type time);
123         void callback();
124
125     private:
126         detail::EventBinding<void> & binding();
127     };
128
129 #endif
130
131     /** \brief Event implementation base class
132
133         EventImplementation provides the base-class for all Event implementations. 
134         \code
135         class SomeEvent : public EventImplementation<SomeEventArg>
136         {
137         public:
138             SomeEvent() {}
139
140         private:
141             virtual void v_enable() {
142                 // register cb() to be called when the event occurs
143             }
144
145             virtual void v_disable() {
146                 // unregister cb()
147             }
148
149             void cb() {
150                 // Build event argument
151                 SomeEventArg arg (...); 
152                 // Call the event callback
153                 callback(arg);
154             }
155         };
156         \endcode
157
158         Every event needs to implement v_enable() and v_disable(). v_enable() should register some
159         member (in the example \c cb() ) to be called whenever the event occurs, while v_disable()
160         should unregister it.
161
162         The \a EventType argument to EventImplementation defines the type of argument passed to the
163         user callback. It defaults to \c void. . This user callback is called from within the
164         registered member (e.g. \c cb() ) by calling the inherited callback() member. This member
165         takes an \a EventType reference as argument which will be forwarded to the user callback. If
166         available, you should also provide the \e expected event time as a second argument.
167      */
168     template <class EventType>
169     class EventImplementation
170         : public EventDescriptor, 
171           public EventImplementationHelper< EventType, EventImplementation<EventType> >
172     {
173     public:
174         typedef EventType Event;
175         typedef typename detail::EventArgType<EventType>::type EventArg;
176
177         module::Module & module() const; ///< Module in which the event is registered
178         EventManager & manager() const; ///< EventManager of the event
179         
180     protected:
181         EventImplementation();
182
183     private:
184         virtual bool v_isRegistered();
185         void setBinding(detail::EventBinding<Event> & binding);
186
187         detail::EventBinding<Event> * binding_;
188
189         friend class EventManager;
190         friend class EventImplementationHelper< EventType, EventImplementation<EventType> >;
191     };
192
193 }}
194
195 ///////////////////////////////hh.e////////////////////////////////////////
196 #include "Events.cci"
197 //#include "Events.ct"
198 #include "Events.cti"
199 #endif
200
201 \f
202 // Local Variables:
203 // mode: c++
204 // fill-column: 100
205 // c-file-style: "senf"
206 // indent-tabs-mode: nil
207 // ispell-local-dictionary: "american"
208 // compile-command: "scons -u test"
209 // comment-column: 40
210 // End: