Packets: Fix VariantParser invalid parser access bug
[senf.git] / PPI / Joins.hh
index 88b72d5..266e807 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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
@@ -23,8 +23,8 @@
 /** \file
     \brief Joins public header */
 
-#ifndef HH_Joins_
-#define HH_Joins_ 1
+#ifndef HH_SENF_PPI_Joins_
+#define HH_SENF_PPI_Joins_ 1
 
 // Custom includes
 #include <boost/ptr_container/ptr_vector.hpp>
@@ -41,58 +41,112 @@ namespace ppi {
 #ifndef DOXYGEN
 
     template <class Source>
-    connector::PassiveInput & connect(Source & source, module::PassiveJoin & target);
-    
+    connector::GenericPassiveInput & connect(Source & source, module::PassiveJoin & target);
+
     template <class Source>
-    connector::ActiveInput & connect(Source & source, module::PriorityJoin & target);
+    connector::GenericActiveInput & connect(Source & source, module::PriorityJoin & target);
 
 #endif
 
 namespace module {
 
+    /** \brief Join multiple packet streams with passive inputs
+
+        The PassiveJoin will combine any number of packet streams. You may connect any number of
+        ActiveOutput<>'s  to the PassiveJoin instance. The combined stream is then provided on the
+        ActiveOutput<> \a output.
+
+        Since PassiveJoin allows any number of incoming packet streams, the input connectors are
+        dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
+        the needed input connectors. This hides this extra functionality from the user.
+        \code
+        senf::ppi::module::PassiveJoin join;
+
+        ppi::connect(module1,join);             // Connect first module to join's input
+        ppi::connect(module2.some_output,join); // Connect another module to join's input
+        ppi::connect(join,module3);             // Forward combined stream to module3
+        \endcode
+
+        \ingroup routing_modules
+     */
     class PassiveJoin
         : public Module
     {
         SENF_PPI_MODULE(PassiveJoin);
     public:
-        connector::ActiveOutput output;
+        connector::ActiveOutput<> output;
 
         PassiveJoin();
 
+    private:
+        connector::PassiveInput<> & newInput();
+
+#ifndef DOXYGEN
+        // I didn't get template friend functions to work ...
+    public:
+#endif
         template <class Source>
-        connector::PassiveInput & connect(Source & source);
+        connector::GenericPassiveInput & connect(Source & source);
 
     private:
-        connector::PassiveInput & newInput();
-
-        void request(connector::PassiveInput & input);
+        void request(connector::GenericPassiveInput & input);
         void onThrottle();
         void onUnthrottle();
 
-        typedef boost::ptr_vector<connector::PassiveInput> Inputs;
+        typedef boost::ptr_vector<connector::PassiveInput<> > Inputs;
         Inputs inputs_;
     };
 
+    /** \brief Join multiple packet streams with active inputs
+
+        The PriorityJoin will combine any number of packet streams. You may connect any number of
+        PassiveInput<>'s  to the PassiveJoin instance. The combined stream is then provided on the
+        PassiveOutput<> \a output.
+
+        When a packet request is received on Priorityjoin's \a output, The request will be serviced
+        from the first unthrottled input. The order, in which connectors are connected to the
+        PriorityJoin's input is important: The earlier connected peer has the higher priority and
+        will be serviced first.
+
+        Since PriorityJoin allows any number of incoming packet streams, the input connectors are
+        dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
+        the needed input connectors. This hides this extra functionality from the user.
+        \code
+        senf::ppi::module::PriorityJoin join;
+
+        ppi::connect(module1,join);             // Connect first module to join's input
+        ppi::connect(module2.some_output,join); // Connect another module to join's input
+        ppi::connect(join,module3);             // Forward combined stream to module3
+        \endcode
+        Here, \a module1 has higher priority than \a module2 which will only be queried if \a
+        module1 is throttled.
+
+        \ingroup routing_modules
+     */
     class PriorityJoin
         : public Module
     {
         SENF_PPI_MODULE(PriorityJoin);
     public:
-        connector::PassiveOutput output;
+        connector::PassiveOutput<> output;
 
         PriorityJoin();
 
+    private:
+        connector::ActiveInput<> & newInput();
+
+#ifndef DOXYGEN
+    public:
+#endif
         template <class Source>
-        connector::ActiveInput & connect(Source & source);
+        connector::GenericActiveInput & connect(Source & source);
 
     private:
-        connector::ActiveInput & newInput();
-
         void request();
         void onThrottle();
         void onUnthrottle();
 
-        typedef boost::ptr_vector<connector::ActiveInput> Inputs;
+        typedef boost::ptr_vector<connector::ActiveInput<> > Inputs;
         Inputs inputs_;
     };