Replace SENFSCons.InstallIncludeFiles with InstallSubdir builder calls
[senf.git] / PPI / Joins.hh
index 7276384..6c260c0 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
 /** \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>
 #include "predecl.hh"
 #include "Connectors.hh"
 #include "Module.hh"
+#include "MultiConnectorMixin.hh"
 
 //#include "Joins.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 namespace senf {
 namespace ppi {
 
-    template <class Source>
-    connector::PassiveInput & connect(Source & source, module::PassiveJoin & target);
-    
-    template <class Source>
-    connector::ActiveInput & connect(Source & source, module::PriorityJoin & target);
-
 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
+        : public Module,
+          public MultiConnectorMixin<PassiveJoin, connector::PassiveInput<> >
     {
         SENF_PPI_MODULE(PassiveJoin);
     public:
-        connector::ActiveOutput output;
+        connector::ActiveOutput<> output;
 
         PassiveJoin();
 
-        template <class Source>
-        connector::PassiveInput & connect(Source & source);
-
     private:
-        connector::PassiveInput & newInput();
-
-        void request(connector::PassiveInput & input);
+        void connectorSetup(connector::PassiveInput<> & conn);
+        void request(connector::GenericPassiveInput & input);
         void onThrottle();
         void onUnthrottle();
 
-        typedef boost::ptr_vector<connector::PassiveInput> Inputs;
-        Inputs inputs_;
+        friend class MultiConnectorMixin<PassiveJoin, connector::PassiveInput<> >;
     };
 
+    /** \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
+        : public Module,
+          public MultiConnectorMixin<PriorityJoin, connector::ActiveInput<> >
     {
         SENF_PPI_MODULE(PriorityJoin);
     public:
-        connector::PassiveOutput output;
+        connector::PassiveOutput<> output;
 
         PriorityJoin();
 
-        template <class Source>
-        connector::ActiveInput & connect(Source & source);
-
     private:
-        connector::ActiveInput & newInput();
-
+        void connectorSetup(PriorityJoin::ConnectorType & conn, int priority=-1);
         void request();
         void onThrottle();
         void onUnthrottle();
 
-        typedef boost::ptr_vector<connector::ActiveInput> Inputs;
-        Inputs inputs_;
+        friend class MultiConnectorMixin<PriorityJoin, connector::ActiveInput<> >;
     };
 
 }}}
@@ -97,7 +129,7 @@ namespace module {
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Joins.cci"
 //#include "Joins.ct"
-#include "Joins.cti"
+//#include "Joins.cti"
 #endif
 
 \f