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