PPI: Add senf::connect() packet type compatibility check documentation
[senf.git] / PPI / Connectors.hh
index ee07dc0..60b1f71 100644 (file)
@@ -31,6 +31,7 @@
 #include <boost/utility.hpp>
 #include <boost/scoped_ptr.hpp>
 #include "../Utils/safe_bool.hh"
+#include "../Utils/Exception.hh"
 #include "../Packets/Packets.hh"
 #include "predecl.hh"
 #include "detail/Callback.hh"
@@ -47,8 +48,8 @@ namespace connector {
         \brief Connector classes
 
         A connector has two independent properties
-        \li it may be \e active or \e passive
-        \li it may be an \e input or an \e output
+        - it may be \e active or \e passive
+        - it may be an \e input or an \e output
 
         \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
@@ -58,10 +59,10 @@ namespace connector {
         input modules possess a packet queue.
 
         We therefore have 4 connector types:
-        \li senf::ppi::connector::ActiveInput
-        \li senf::ppi::connector::ActiveOutput
-        \li senf::ppi::connector::PassiveInput
-        \li senf::ppi::connector::PassiveOutput.
+        - senf::ppi::connector::ActiveInput
+        - senf::ppi::connector::ActiveOutput
+        - senf::ppi::connector::PassiveInput
+        - senf::ppi::connector::PassiveOutput.
 
         Connectors are declared as module data members and are then externally connected to other
         modules.
@@ -99,6 +100,9 @@ namespace connector {
             \ref ppi_connectors
      */
 
+    struct IncompatibleConnectorsException : public senf::Exception
+    { IncompatibleConnectorsException() : senf::Exception("Incompatible connectors") {} };
+
     /** \brief Connector base-class
 
         This connector provides access to the generic connector facilities. This includes the
@@ -119,6 +123,8 @@ namespace connector {
         void connect(Connector & target);
 
     private:
+        virtual std::type_info const & packetTypeID();
+
         void setModule(module::Module & module);
 
         Connector * peer_;
@@ -136,9 +142,9 @@ namespace connector {
 
         Passive connectors always handle two throttling states:
 
-        \li The \e native throttling state is set manually by the module. It is the throttling state
+        - The \e native throttling state is set manually by the module. It is the throttling state
             originating in the current module
-        \li The \e forwarded throttling state is the state as it is received by throttling
+        - The \e forwarded throttling state is the state as it is received by throttling
             notifications
 
         The accumulative throttling state is generated by combining all sub-states.
@@ -450,19 +456,23 @@ namespace connector {
 
 #   define TypedConnector_Input read
 #   define TypedConnector_Output write
-#   define TypedConnector(type, dir)                                                              \
+#   define TypedConnector(pType, dir)                                                             \
         template <class PacketType>                                                               \
-        class type ## dir                                                                         \
-            : public Generic ## type ## dir,                                                      \
-              private detail::Typed ## dir ## Mixin<type ## dir <PacketType>, PacketType>         \
+        class pType ## dir                                                                        \
+            : public Generic ## pType ## dir,                                                     \
+              private detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType>        \
         {                                                                                         \
-            typedef detail::Typed ## dir ## Mixin<type ## dir <PacketType>, PacketType> mixin;    \
+            typedef detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType> mixin;   \
         public:                                                                                   \
             using mixin::operator();                                                              \
             using mixin::TypedConnector_ ## dir ;                                                 \
+        private:                                                                                  \
+            virtual std::type_info const & packetTypeID()                                         \
+                { return typeid(typename PacketType::type); }                                     \
+            friend class detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType>;    \
         };                                                                                        \
         template <>                                                                               \
-        class type ## dir <Packet> : public Generic ## type ## dir                                \
+        class pType ## dir <Packet> : public Generic ## pType ## dir                              \
         {}
 
     TypedConnector( Passive, Input  );
@@ -477,15 +487,17 @@ namespace connector {
 #else
 
     /** \brief Connector actively reading packets
+        
+        \tparam PacketType Type of packet to read. Defaults to senf::Packet
 
         The ActiveInput connector template reads data actively from a connected module. This class
         is completely implemented via it's base-class, GenericActiveInput, the only difference is
         that read packets are returned as \a PacketType instead of generic senf::Packet references.
 
         \see GenericActiveInput \n
-            senf::ppi::connectro
+            senf::ppi::connector
      */
-    template <class PacketType>
+    template <class PacketType=Packet>
     class ActiveInput : public GenericActiveInput
     {
     public:
@@ -498,6 +510,8 @@ namespace connector {
 
     /** \brief Connector passively receiving packets
 
+        \tparam PacketType Type of packet to read. Defaults to senf::Packet
+
         The PassiveInput connector template receives packets sent to it from a connected
         module. This class is completely implemented via it's base-class, GenericPassiveInput, the
         only difference is that read packets are returned as \a PacketType instead of generic
@@ -519,6 +533,8 @@ namespace connector {
 
     /** \brief Connector actively sending packets
 
+        \tparam PacketType Type of packet to send. Defaults to senf::Packet
+
         The ActiveOutput connector template sends data actively to a connected module. This class is
         completely implemented via it's base-class, GenericActiveOutput, the only difference is that
         it only sends packets of type \a PacketType.
@@ -526,16 +542,18 @@ namespace connector {
         \see GenericActiveOutput \n
             senf::ppi::connector
      */
-    template <class PacketType>
+    template <class PacketType=Packet>
     class ActiveOutput : public GenericActiveOutput
     {
     public:
-        PacketType operator()();
-        PacketType write();
+        operator()(PacketType packet);  ///< Send out a packet
+        write(PacketType packet);       ///< Alias for operator()
     };
 
     /** \brief Connector passively providing packets
 
+        \tparam PacketType Type of packet to send. Defaults to senf::Packet
+
         The PassiveOutput connector template provides data passively to a connected module whenever
         signaled. This class is completely implemented via it's base-class, GenericPassiveOutput, the
         only difference is that it only sends packets of type \a PacketType.
@@ -543,12 +561,12 @@ namespace connector {
         \see GenericPassiveOutput \n
             senf::ppi::connector
      */
-    template <class PacketType>
+    template <class PacketType=Packet>
     class PassiveOutput : public GenericPassiveOutput
     {
     public:
-        PacketType operator()();
-        PacketType write();
+        operator()(PacketType packet);  ///< Send out a packet
+        write(PacketType packet);       ///< Alias for operator()
     };
 
 #endif