Utils/Termlib: Extend the completion API
[senf.git] / PPI / Connectors.hh
index 2750224..78b7023 100644 (file)
@@ -23,8 +23,8 @@
 /** \file
     \brief Connectors public header */
 
-#ifndef HH_Connectors_
-#define HH_Connectors_ 1
+#ifndef HH_SENF_PPI_Connectors_
+#define HH_SENF_PPI_Connectors_ 1
 
 // Custom includes
 #include <deque>
@@ -36,6 +36,7 @@
 #include "predecl.hh"
 #include "detail/Callback.hh"
 #include "Queueing.hh"
+#include "ModuleManager.hh"
 
 //#include "Connectors.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -53,11 +54,11 @@ namespace connector {
         \li it has an (optional) packet type
 
         \e Active connectors are activated from within the module, \e passive connectors are
-        signaled by the external framework. \e Input modules receive packets, \e output modules send
-        packets.
+        signaled by the external framework. \e Input connectors receive packets, \e output
+        connectors send packets.
 
         All passive connectors call some onRequest callback whenever I/O needs to be performed. All
-        input modules possess a packet queue.
+        input connectors possess a packet queue.
 
         We therefore have 4 connector types each of which is parameterized by the type of packet
         traversing the connector:
@@ -90,12 +91,48 @@ namespace connector {
         private:
             void onRequest() {
                 // 'input()' will return a senf::EthernetPacket packet handle
-                try { output( input().find<IpPacket>() ); }
+                try { output( input().find<senf::IpPacket>() ); }
                 catch (senf::InvalidPacketChainException & ex) { ; }
             }
         };
         \endcode
 
+
+        \section ppi_jacks Jacks
+
+        A Jack is a packet type aware and possibly packet type converting reference to an arbitrary
+        connector of the same type. Jacks are used in groups to indirectly declare the input's and
+        output's
+
+        \code
+        class MyGroup
+        {
+        private:
+            senf::ppi::module::PassiveQueue queue;
+            senf::ppi::module::RateAnalyzer analyzer;
+
+        public:
+            senf::ppi::connector::ActiveInputJack<senf::EthernetPacket> input;
+            senf::ppi::connector::ActiveOutputJack<senf::EthernetPacket> output;
+
+            MyGroup() 
+                : queue (), analyzer (), input (queue.input), output (analyzer.output)
+            {
+                senf::ppi::connect(queue, analyzer);
+            }
+        };
+        \endcode
+
+        The jacks are initialized by passing an arbitrary compatible connector to the jack
+        constructor. A connector is compatible, if
+        \li It has the same input/output active/passive specification
+        \li Either the Jack or the Connector are generic (senf::Packet) or Jack and Connector have
+            the same packet type
+
+        Jacks can be used wherever connectors may be used. Jacks may be defined anywhere, not only
+        in modules. It is however important to ensure that the lifetime of the jack does not exceed
+        the lifetime of the referenced connector.
+
         \see
             senf::ppi::module::Module \n
             senf::ppi::connect() \n
@@ -122,18 +159,22 @@ namespace connector {
         to the containing module)
      */
     class Connector
-        : boost::noncopyable
+        : ModuleManager::Initializable, boost::noncopyable
     {
     public:
         Connector & peer() const;       ///< Get peer connected to this connector
         module::Module & module() const; ///< Get this connectors containing module
 
+        bool connected() const;         ///< \c true, if connector connected, \c false otherwise
+
+        void disconnect();              ///< Disconnect connector from peer
+
     protected:
         Connector();
         virtual ~Connector();
 
         void connect(Connector & target);
-
+        
     private:
         virtual std::type_info const & packetTypeID();
 
@@ -193,6 +234,8 @@ namespace connector {
         void emit();
 
     private:
+        virtual void v_init();
+
         // Called by the routing to change the remote throttling state
         void notifyThrottle();          ///< Forward a throttle notification to this connector
         void notifyUnthrottle();        ///< Forward an unthrottle notification to this connector
@@ -268,6 +311,8 @@ namespace connector {
         ActiveConnector();
 
     private:
+        virtual void v_init();
+
         // called by the peer() to forward throttling notifications
         void notifyThrottle();
         void notifyUnthrottle();
@@ -281,6 +326,8 @@ namespace connector {
         typedef std::vector<ForwardingRoute*> NotifyRoutes;
         NotifyRoutes notifyRoutes_;
 
+        bool throttled_;        
+
         friend class senf::ppi::ForwardingRoute;
         friend class PassiveConnector;
     };
@@ -339,7 +386,7 @@ namespace connector {
         InputConnector();
 
     private:
-        void enqueue(Packet p);
+        void enqueue(Packet const & p);
 
         virtual void v_requestEvent();
         virtual void v_enqueueEvent();
@@ -360,9 +407,9 @@ namespace connector {
         : public virtual Connector
     {
     public:
-        void operator()(Packet p);      ///< Send out a packet
+        void operator()(Packet const & p);      ///< Send out a packet
 
-        void write(Packet p);           ///< Alias for operator()(Packet p)
+        void write(Packet const & p);           ///< Alias for operator()(Packet p)
 
         InputConnector & peer() const;
 
@@ -515,7 +562,7 @@ namespace connector {
     {
     public:
         PacketType operator()();        ///< Read packet
-                                        /**< \throws std::bad_cast, if the %connector receives a
+                                        /**< \throws std::bad_cast if the %connector receives a
                                              Packet which is not of type \a PacketType.
                                              \returns newly read packet reference. */
         PacketType read();              ///< Alias for operator()
@@ -538,7 +585,7 @@ namespace connector {
     {
     public:
         PacketType operator()();        ///< Read packet
-                                        /**< \throws std::bad_cast, if the %connector receives a
+                                        /**< \throws std::bad_cast if the %connector receives a
                                              Packet which is not of type \a PacketType.
                                              \returns newly read packet reference. */
         PacketType read();              ///< Alias for operator()
@@ -560,7 +607,7 @@ namespace connector {
     {
     public:
         operator()(PacketType packet);  ///< Send out a packet
-        write(PacketType packet);       ///< Alias for operator()
+        void write(PacketType packet);  ///< Alias for operator()
     };
 
     /** \brief Connector passively providing packets
@@ -580,7 +627,7 @@ namespace connector {
     {
     public:
         operator()(PacketType packet);  ///< Send out a packet
-        write(PacketType packet);       ///< Alias for operator()
+        void write(PacketType packet);  ///< Alias for operator()
     };
 
 #endif