#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"
/** \namespace senf::ppi::connector
\brief Connector classes
- A connector has two independent properties
- - it may be \e active or \e passive
- - it may be an \e input or an \e output
+ A connector has three independent properties
+ \li it may be \e active or \e passive
+ \li it may be an \e input or an \e output
+ \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
All passive connectors call some onRequest callback whenever I/O needs to be performed. All
input modules possess a packet queue.
- We therefore have 4 connector types:
- - senf::ppi::connector::ActiveInput
- - senf::ppi::connector::ActiveOutput
- - senf::ppi::connector::PassiveInput
- - senf::ppi::connector::PassiveOutput.
+ We therefore have 4 connector types each of which is parameterized by the type of packet
+ traversing the connector:
+ \li senf::ppi::connector::ActiveInput
+ \li senf::ppi::connector::ActiveOutput
+ \li senf::ppi::connector::PassiveInput
+ \li senf::ppi::connector::PassiveOutput.
Connectors are declared as module data members and are then externally connected to other
modules.
\ref ppi_connectors
*/
+ /** \brief Incompatible connectors connected
+
+ This exception is thrown, when two incompatible connectors are connected. This happens if
+ both connectors of a senf::ppi::connect() statement declare a packet type (the connector
+ template argument) but they don't declare the same packet type.
+
+ You need to ensure, that both connectors use the same packet type.
+
+ \see senf::ppi::connect()
+ */
+ 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
void connect(Connector & target);
private:
+ virtual std::type_info const & packetTypeID();
+
void setModule(module::Module & module);
Connector * peer_;
# 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: \
- friend class detail::Typed ## dir ## Mixin<type ## dir <PacketType>, PacketType>; \
+ 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 );
\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.
+ 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::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()
\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
+ 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
senf::Packet references.
\see GenericPassiveInput \n
{
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()
\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.
+ 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.
\see GenericActiveOutput \n
senf::ppi::connector
\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.
+ 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.
\see GenericPassiveOutput \n
senf::ppi::connector