2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
22 \brief Module public header
30 #include <boost/utility.hpp>
31 #include <boost/ptr_container/ptr_vector.hpp>
32 #include "Scheduler/ClockService.hh"
35 //#include "Module.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
42 /** \brief Module base-class
44 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
45 with interfaces to several PPI facilities:
47 \li Connector management
48 \li Flow management (routing)
51 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
52 this base class. This is an example module specification:
54 class SomeModule : public senf::ppi::module::Module
56 SENF_PPI_MODULE(SomeModule);
58 senf::FileHandle handle;
60 // If needed, define events
61 senf::ppi::IOEvent event;
64 // Define connectors. Any number and type of connectors may be defined. Connectors
65 // must be public since they need to be accessed to connect modules with each other.
66 senf::ppi::connector::PassiveInput input;
67 senf::ppi::connector::ActiveOutput output;
69 SomeModule(senf::FileHandle h)
71 event ( handle, senf::ppi::IOEvent::Read )
73 // Set up routing. If some connector is not routed you need to explicitly state this
75 route( input, output );
76 route( event, output )
77 .autoThrottling( false );
79 // Register event handlers
80 registerEvent( &SomeModule::read, event );
82 // Register passive connector handlers
83 input.onRequest( &SomeModule::outputRequest );
85 // If needed, you may register throttling event handlers
86 output.onThrottle( &SomeModule::throttle );
87 output.onUnthrottle( &SomeModule::unthrottle );
91 // Called whenever the 'handle' is readable. Read data, do processing and so
92 // on. This example reads the data, puts it into an ethernet packet and sends the
93 // packet out via the active output.
94 output(senf::EthernetPacket::create(handle.read()))
97 void outputRequest() {
98 // Called whenever a packet is sent into the input to. Here we just forward it to
99 // the output if it is an EthernetPacket
100 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
106 // Called whenever a throttle notification comes in. Here, we just disable the
107 // event (which is stupid since we should just not have disabled autoThrottling on
108 // the route but this is only an example which tries to be simple ...)
112 void onUnthrottle() {
113 // and for unthrottle notifications
120 If your module only has a single input connector, you should call this connector \c
121 input. If it has only a single output connector, you should call it \c output. This allows
122 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
133 template <class Source, class Target>
134 Route<Source, Target> & route(Source & source, Target & target);
135 ///< Define flow information
136 /**< Using the route() and noroute() members, the
137 information flow within the module is defined. Routing
138 may be specified either between inputs, outputs and
139 events. The routing information is used to perform
140 automatic throttling. The throttling behavior may
141 however be controlled manually.
143 Even if no automatic throttling is desired <em>it is
144 vital to define the flow information for all inputs and
145 outputs</em>. Without flow information important
146 internal state of the module cannot be
147 initialized. This includes, explicitly defining
148 terminal inputs and outputs using noroute. Event
149 routing however is optional.
151 The return value may be used to alter routing
152 parameters like throttling parameters.
154 \param[in] source Data source, object which controls
156 \param[in] target Data target, object which controls
158 \returns Route instance describing this route */
160 void noroute(connector::Connector & connector); ///< Define terminal connectors
161 /**< The noroute() member explicitly declares, that a
162 connector is terminal and does not directly
163 receive/forward data from/to some other
164 connector. <em>It is mandatory to define routing
165 information for terminal connectors</em>.
167 See the route() documentation for more on routing
169 \param[in] connector Terminal connector to declare */
171 template <class Target, class Descriptor>
172 void registerEvent(Target target, Descriptor & descriptor);
173 ///< Register an external event
174 /**< The \a target argument may be either an arbitrary
175 callable object or it may be a member function pointer
176 pointing to a member function of the Module derived
177 classed. The handler may \e optionally take an Argument
178 of type <tt>Descriptor::Event const &</tt>. This object
179 allows to access detailed information on the event
182 The \a descriptor describes the event to signal. This
184 may be a timer event or some type of I/O event on a
185 file descriptor or socket.
187 \param[in] target The handler to call whenever the
189 \param[in] descriptor The type of event to register */
191 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
192 /**< If available, this returns the scheduled time of the
195 ClockService::clock_type now() const; ///< Current time of the currently processing event
198 virtual void macro_SENF_PPI_MODULE_missing() = 0;
210 EventManager & eventManager() const;
211 ModuleManager & moduleManager() const;
213 void registerConnector(connector::Connector & connector);
214 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
216 typedef std::vector<connector::Connector *> ConnectorRegistry;
217 ConnectorRegistry connectorRegistry_;
219 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
220 RouteInfoBase routes_;
222 template <class Source, class Target>
223 friend class detail::RouteHelper;
224 friend class senf::ppi::ModuleManager;
227 # define SENF_PPI_MODULE(name) \
229 ~ name() { destroy(); } \
230 void macro_SENF_PPI_MODULE_missing() {} \
235 ///////////////////////////////hh.e////////////////////////////////////////
236 #include "Module.cci"
238 //#include "Module.cti"
245 // c-file-style: "senf"
246 // indent-tabs-mode: nil
247 // ispell-local-dictionary: "american"
248 // compile-command: "scons -u test"
249 // comment-column: 40