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