Fix SCons 1.2.0 build failure
[senf.git] / PPI / Module.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 Module public header 
25 */
26
27 #ifndef HH_SENF_PPI_Module_
28 #define HH_SENF_PPI_Module_ 1
29
30 // Custom includes
31 #include <vector>
32 #include <boost/utility.hpp>
33 #include <boost/ptr_container/ptr_vector.hpp>
34 #include "../Scheduler/ClockService.hh"
35 #include "predecl.hh"
36 #include "ModuleManager.hh"
37
38 //#include "Module.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42 namespace ppi {
43 namespace module {
44
45     /** \namespace senf::ppi::module
46         \brief PPI Modules
47        
48         The modules build the PPI core. The PPI provides a set of general purpose infrastructure
49         modules. For concrete applications, additional application specific processing modules need
50         to be implemented.
51
52         \section module_impl Implementing Modules
53         
54         All modules derive from senf::ppi::module::Module. See this class for a documentation on how
55         to write new modules.
56
57         \section infrastructure_modules General Purpose Modules
58
59         The PPI provided general purpose modules can be grouped into several categories
60
61         \li \ref io_modules receive external data or forward packets out of the PPI
62         \li \ref routing_modules forward packets within the network
63         \li \ref adapter_modules are used to connect incompatible connectors to each other
64      */
65
66     /** \defgroup io_modules Source/Sink Modules
67
68         Source and Sink modules generate or absorb packets in some way: Reading data from a file
69         descriptor, discarding packets etc.
70      */
71
72     /** \defgroup routing_modules Routing Modules
73
74         Routing modules perform packet forwarding within the network. They do not process the packet
75         data, they just route it.
76      */
77
78     /** \defgroup adapter_modules Adapter Modules
79
80         Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
81         active or passive connectors.
82      */
83
84     /** \brief Module base-class
85
86         senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
87         with interfaces to several PPI facilities:
88         
89         \li Connector management
90         \li Flow management (routing)
91         \li Event handling
92
93         To provide internal bookkeeping, most access to the PPI infrastructure is managed through
94         this base class. This is an example module specification:
95         \code
96         class SomeModule : public senf::ppi::module::Module
97         {
98             SENF_PPI_MODULE(SomeModule);
99
100             senf::FileHandle handle;
101
102             // If needed, define events
103             senf::ppi::IOEvent event;
104
105         public:
106             // Define connectors. Any number and type of connectors may be defined. Connectors
107             // must be public since they need to be accessed to connect modules with each other.
108             senf::ppi::connector::PassiveInput<> input;
109             senf::ppi::connector::ActiveOutput<> output;
110
111             SomeModule(senf::FileHandle h) 
112               : handle ( h ), 
113                 event  ( handle, senf::ppi::IOEvent::Read )
114             {
115                 // Set up routing. If some connector is not routed you need to explicitly state this
116                 // using noroute()
117                 route( input, output );
118                 route( event, output )
119                     .autoThrottling( false );
120
121                 // Register event handlers
122                 registerEvent( event, &SomeModule::read );
123
124                 // Register passive connector handlers
125                 input.onRequest( &SomeModule::outputRequest );
126
127                 // If needed, you may register throttling event handlers
128                 output.onThrottle( &SomeModule::throttle );
129                 output.onUnthrottle( &SomeModule::unthrottle );
130             }
131
132             void read() {
133                 // Called whenever the 'handle' is readable. Read data, do processing and so
134                 // on. This example reads the data, puts it into an ethernet packet and sends the
135                 // packet out via the active output.
136                 output(senf::EthernetPacket::create(handle.read()))
137             }
138
139             void outputRequest() {
140                 // Called whenever a packet is sent into the input to. Here we just forward it to
141                 // the output if it is an EthernetPacket
142                 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
143                 if (p)
144                     output(p);
145             }
146
147             void onThrottle() {
148                 // Called whenever a throttle notification comes in. Here, we just disable the
149                 // event (which is stupid since we should just not have disabled autoThrottling on
150                 // the route but this is only an example which tries to be simple ...)
151                 event.disable();
152             }
153
154             void onUnthrottle() {
155                 // and for unthrottle notifications
156                 event.enable();
157             }
158
159             void v_init() {
160                 // Optional. Called after before running the module but after connections have been
161                 // set up. This is either directly before senf::ppi::run() or senf::ppi::init() is
162                 // called or, for modules created while the PPI is already running, after returning
163                 // from all event handlers but before going back to the event loop.
164             }
165
166         };
167         \endcode
168
169         If your module only has a single input connector, you should call this connector \c
170         input. If it has only a single output connector, you should call it \c output. This allows
171         to setup connections without stating the connector explicitly (see senf::ppi::connect()).
172
173         \see \ref ppi_modules
174      */
175     class Module
176         : ModuleManager::Initializable, boost::noncopyable
177     {
178     public:
179         virtual ~Module();
180
181     protected:
182         Module();
183
184 #ifndef DOXYGEN
185         template <class Source, class Target>
186         Route<Source, Target> & route(Source & source, Target & target); 
187 #else
188         Route<connector::InputConnector, connector::OutputConnector> &
189         route(connector::InputConnector & input, connector::OutputConnector & output);
190                                         ///< Define flow information
191                                         /**< Using the route() and noroute() members, the
192                                              information flow within the module is defined. Routing
193                                              may be defined between inputs, outputs and events. The
194                                              routing information is used to perform automatic
195                                              throttling. The throttling behavior may however be
196                                              controlled manually.
197
198                                              Even if no automatic throttling is desired <em>it is
199                                              essential to define the flow information for all inputs
200                                              and outputs</em>. Without flow information important
201                                              internal state of the module cannot be
202                                              initialized. This includes, explicitly defining
203                                              terminal inputs and outputs using noroute. Event
204                                              routing is optional however.
205
206                                              The return value may be used to alter routing
207                                              parameters like throttling parameters.
208
209                                              \param[in] input Data source, object which controls
210                                                  incoming data (connector or event)
211                                              \param[in] output Data target, object which controls
212                                                  outgoing data (connector or event)
213                                              \returns Route instance describing this route 
214                                              \see \ref ppi_throttling
215                                              \note The real implementation is not provided by three
216                                                  overloads but by a single template member */
217
218         Route<connector::InputConnector, EventDescriptor> &
219         route(connector::InputConnector & input, EventDescriptor & output);
220                                         ///< Define flow information
221                                         /**< Route from a connector to an event.  Routing from a
222                                              connector to an event defines the event as the
223                                              conceptual 'receiver' of the data. This means, the
224                                              event is controlling the processing of received data
225                                              packets (Example: Routing from an input to an IOEvent
226                                              defines, that input data will be processed whenever the
227                                              event is signaled.).
228
229                                              This event routing allows to automatically
230                                              enable/disable the event on throttling notifications. 
231
232                                              \see \ref route() */
233
234         Route<EventDescriptor, connector::OutputConnector> &
235         route(EventDescriptor & input, connector::OutputConnector & output);
236                                         ///< Define flow information
237                                         /**< Route from an event to a connector. Routing from an
238                                              event to a connector defines the event as the
239                                              conceptual 'source' of the data. This means, the event
240                                              controls how packets are sent (Example: Routing from an
241                                              IOEvent to an output defines, that output data will be
242                                              generated whenever the event is signaled).
243
244                                              This event routing allows to automatically
245                                              enable/disable the event on throttling notifications. 
246
247                                              \see \ref route() */
248 #endif
249
250         void noroute(connector::Connector & connector); ///< Define terminal connectors
251                                         /**< The noroute() member explicitly declares, that a
252                                              connector is terminal and does not directly
253                                              receive/forward data from/to some other
254                                              connector. <em>It is mandatory to define routing
255                                              information for terminal connectors</em>.
256
257                                              See the route() documentation for more on routing
258                                              
259                                              \param[in] connector Terminal connector to declare */
260
261 #ifndef DOXYGEN
262         template <class Descriptor, class Target>
263         void registerEvent(Descriptor & descriptor, Target target);
264 #else
265         template <class Target>
266         void registerEvent(EventDescriptor & descriptor, Target target);
267                                         ///< Register an external event
268                                         /**< The \a target argument may be either an arbitrary
269                                              callable object or it may be a member function pointer
270                                              pointing to a member function of the Module derived
271                                              classed. The handler may \e optionally take an Argument
272                                              of type <tt>Descriptor::Event const &</tt>. This object
273                                              allows to access detailed information on the event
274                                              delivered.
275
276                                              The \a descriptor describes the event to signal like a
277                                              timer event or some type of I/O event on a file
278                                              descriptor or socket.
279
280                                              \param[in] target The handler to call whenever the
281                                                  event is signaled
282                                              \param[in] descriptor The type of event to register 
283                                              \note The real implementation has the second arguments
284                                                  type as an additional template parameter. */
285 #endif
286
287         ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
288                                         /**< If available, this returns the scheduled time of the
289                                              event. */
290
291         ClockService::clock_type now() const; ///< Current time of the currently processing event
292
293 #ifndef DOXYGEN
294         virtual void macro_SENF_PPI_MODULE_missing() = 0;
295
296     private:
297 #endif
298         virtual void v_init();          ///< Called after module setup
299                                         /**< This member is called directly before the PPI (resumes)
300                                              execution. It is called after connections have been
301                                              setup before entering the PPI main loop. 
302
303                                              You may overload this member. Your overload should
304                                              always call the base-class implementation. */
305
306 #ifndef DOXYGEN
307     public:
308 #endif
309         void destroy();
310         
311     private:
312         EventManager & eventManager() const;
313         ModuleManager & moduleManager() const;
314         
315         void registerConnector(connector::Connector & connector);
316         RouteBase & addRoute(std::auto_ptr<RouteBase> route);
317
318         typedef std::vector<connector::Connector *> ConnectorRegistry;
319         ConnectorRegistry connectorRegistry_;
320
321         typedef boost::ptr_vector<RouteBase> RouteInfoBase;
322         RouteInfoBase routes_;
323
324         template <class Source, class Target>
325         friend class detail::RouteHelper;
326         friend class senf::ppi::ModuleManager;
327     };
328
329     /** \brief Define PPI Module
330
331         Every module must begin by using this macro. 
332
333         \see senf::ppi::module::Module
334      */
335 #   define SENF_PPI_MODULE(name)                                                                  \
336     public:                                                                                       \
337         ~ name() { destroy(); }                                                                   \
338         void macro_SENF_PPI_MODULE_missing() {}                                                   \
339     private:
340
341 }}}
342
343 ///////////////////////////////hh.e////////////////////////////////////////
344 #include "Module.cci"
345 #include "Module.ct"
346 //#include "Module.cti"
347 #endif
348
349 \f
350 // Local Variables:
351 // mode: c++
352 // fill-column: 100
353 // c-file-style: "senf"
354 // indent-tabs-mode: nil
355 // ispell-local-dictionary: "american"
356 // compile-command: "scons -u test"
357 // comment-column: 40
358 // End: