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