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