Packets: Fix VariantParser invalid parser access bug
[senf.git] / PPI / Module.hh
index aac6bfa..97f1c11 100644 (file)
@@ -1,6 +1,8 @@
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
     \brief Module public header 
 */
 
-#ifndef HH_Module_
-#define HH_Module_ 1
+#ifndef HH_SENF_PPI_Module_
+#define HH_SENF_PPI_Module_ 1
 
 // Custom includes
 #include <vector>
 #include <boost/utility.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
-#include "Scheduler/ClockService.hh"
+#include "../Scheduler/ClockService.hh"
 #include "predecl.hh"
+#include "ModuleManager.hh"
 
 //#include "Module.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -56,21 +59,16 @@ namespace module {
         The PPI provided general purpose modules can be grouped into several categories
 
         \li \ref io_modules receive external data or forward packets out of the PPI
-        \li \ref sourcesink_modules generate or absorb packets internally
         \li \ref routing_modules forward packets within the network
         \li \ref adapter_modules are used to connect incompatible connectors to each other
-     */
-
-    /** \defgroup io_modules Input/Output Modules
 
-        Input/Output Modules receive data from external sources or forward data from the PPI to
-        outside targets.
+        \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
      */
 
-    /** \defgroup sourcesink_modules Source/Sink Modules
+    /** \defgroup io_modules Source/Sink Modules
 
-        Source and Sink modules generate or absorb packets internally. In contrast to \ref
-        io_modules, they do not communicate outside the PPI.
+        Source and Sink modules generate or absorb packets in some way: Reading data from a file
+        descriptor, discarding packets etc.
      */
 
     /** \defgroup routing_modules Routing Modules
@@ -109,8 +107,8 @@ namespace module {
         public:
             // Define connectors. Any number and type of connectors may be defined. Connectors
             // must be public since they need to be accessed to connect modules with each other.
-            senf::ppi::connector::PassiveInput input;
-            senf::ppi::connector::ActiveOutput output;
+            senf::ppi::connector::PassiveInput<> input;
+            senf::ppi::connector::ActiveOutput<> output;
 
             SomeModule(senf::FileHandle h) 
               : handle ( h ), 
@@ -123,7 +121,7 @@ namespace module {
                     .autoThrottling( false );
 
                 // Register event handlers
-                registerEvent( &SomeModule::read, event );
+                registerEvent( event, &SomeModule::read );
 
                 // Register passive connector handlers
                 input.onRequest( &SomeModule::outputRequest );
@@ -160,15 +158,24 @@ namespace module {
                 event.enable();
             }
 
+            void v_init() {
+                // Optional. Called after before running the module but after connections have been
+                // set up. This is either directly before senf::ppi::run() or senf::ppi::init() is
+                // called or, for modules created while the PPI is already running, after returning
+                // from all event handlers but before going back to the event loop.
+            }
+
         };
         \endcode
 
         If your module only has a single input connector, you should call this connector \c
         input. If it has only a single output connector, you should call it \c output. This allows
         to setup connections without stating the connector explicitly (see senf::ppi::connect()).
+
+        \see \ref ppi_modules
      */
     class Module
-        : boost::noncopyable
+        : ModuleManager::Initializable, boost::noncopyable
     {
     public:
         virtual ~Module();
@@ -176,32 +183,71 @@ namespace module {
     protected:
         Module();
 
+#ifndef DOXYGEN
         template <class Source, class Target>
         Route<Source, Target> & route(Source & source, Target & target); 
+#else
+        Route<connector::InputConnector, connector::OutputConnector> &
+        route(connector::InputConnector & input, connector::OutputConnector & output);
                                         ///< Define flow information
                                         /**< Using the route() and noroute() members, the
                                              information flow within the module is defined. Routing
-                                             may be specified either between inputs, outputs and
-                                             events. The routing information is used to perform
-                                             automatic throttling. The throttling behavior may
-                                             however be controlled manually.
+                                             may be defined between inputs, outputs and events. The
+                                             routing information is used to perform automatic
+                                             throttling. The throttling behavior may however be
+                                             controlled manually.
 
                                              Even if no automatic throttling is desired <em>it is
-                                             vital to define the flow information for all inputs and
-                                             outputs</em>. Without flow information important
+                                             essential to define the flow information for all inputs
+                                             and outputs</em>. Without flow information important
                                              internal state of the module cannot be
                                              initialized. This includes, explicitly defining
                                              terminal inputs and outputs using noroute. Event
-                                             routing however is optional.
+                                             routing is optional however.
 
                                              The return value may be used to alter routing
                                              parameters like throttling parameters.
-                                             
-                                             \param[in] source Data source, object which controls
-                                                 incoming data
-                                             \param[in] target Data target, object which controls
-                                                 outgoing data
-                                             \returns Route instance describing this route */
+
+                                             \param[in] input Data source, object which controls
+                                                 incoming data (connector or event)
+                                             \param[in] output Data target, object which controls
+                                                 outgoing data (connector or event)
+                                             \returns Route instance describing this route 
+                                             \see \ref ppi_throttling
+                                             \note The real implementation is not provided by three
+                                                 overloads but by a single template member */
+
+        Route<connector::InputConnector, EventDescriptor> &
+        route(connector::InputConnector & input, EventDescriptor & output);
+                                        ///< Define flow information
+                                        /**< Route from a connector to an event.  Routing from a
+                                             connector to an event defines the event as the
+                                             conceptual 'receiver' of the data. This means, the
+                                             event is controlling the processing of received data
+                                             packets (Example: Routing from an input to an IOEvent
+                                             defines, that input data will be processed whenever the
+                                             event is signaled.).
+
+                                             This event routing allows to automatically
+                                             enable/disable the event on throttling notifications. 
+
+                                             \see \ref route() */
+
+        Route<EventDescriptor, connector::OutputConnector> &
+        route(EventDescriptor & input, connector::OutputConnector & output);
+                                        ///< Define flow information
+                                        /**< Route from an event to a connector. Routing from an
+                                             event to a connector defines the event as the
+                                             conceptual 'source' of the data. This means, the event
+                                             controls how packets are sent (Example: Routing from an
+                                             IOEvent to an output defines, that output data will be
+                                             generated whenever the event is signaled).
+
+                                             This event routing allows to automatically
+                                             enable/disable the event on throttling notifications. 
+
+                                             \see \ref route() */
+#endif
 
         void noroute(connector::Connector & connector); ///< Define terminal connectors
                                         /**< The noroute() member explicitly declares, that a
@@ -214,8 +260,12 @@ namespace module {
                                              
                                              \param[in] connector Terminal connector to declare */
 
-        template <class Target, class Descriptor>
-        void registerEvent(Target target, Descriptor & descriptor);
+#ifndef DOXYGEN
+        template <class Descriptor, class Target>
+        void registerEvent(Descriptor & descriptor, Target target);
+#else
+        template <class Target>
+        void registerEvent(EventDescriptor & descriptor, Target target);
                                         ///< Register an external event
                                         /**< The \a target argument may be either an arbitrary
                                              callable object or it may be a member function pointer
@@ -225,14 +275,16 @@ namespace module {
                                              allows to access detailed information on the event
                                              delivered.
 
-                                             The \a descriptor describes the event to signal. This
-
-                                             may be a timer event or some type of I/O event on a
-                                             file descriptor or socket.
+                                             The \a descriptor describes the event to signal like a
+                                             timer event or some type of I/O event on a file
+                                             descriptor or socket.
 
                                              \param[in] target The handler to call whenever the
                                                  event is signaled
-                                             \param[in] descriptor The type of event to register */
+                                             \param[in] descriptor The type of event to register 
+                                             \note The real implementation has the second arguments
+                                                 type as an additional template parameter. */
+#endif
 
         ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
                                         /**< If available, this returns the scheduled time of the
@@ -242,12 +294,16 @@ namespace module {
 
 #ifndef DOXYGEN
         virtual void macro_SENF_PPI_MODULE_missing() = 0;
-#endif
 
-#ifndef DOXYGEN
     private:
 #endif
-        virtual void init();            ///< Called just before the network is run
+        virtual void v_init();          ///< Called after module setup
+                                        /**< This member is called directly before the PPI (resumes)
+                                             execution. It is called after connections have been
+                                             setup before entering the PPI main loop. 
+
+                                             You may overload this member. Your overload should
+                                             always call the base-class implementation. */
 
 #ifndef DOXYGEN
     public: