senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ > Class Template Reference

Multi-Connector management. More...

#include <senf/PPI/MultiConnectorMixin.hh>

Inheritance diagram for senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >:

Public Types

typedef ConnectorType_ ConnectorType
 Type of MultiConnector connector. More...
 

Protected Types

typedef ContainerType_ ContainerType
 Type of connector container. More...
 

Protected Member Functions

ContainerType_ & connectors ()
 Get connector container. More...
 
ContainerType_ const & connectors () const
 Get connectors container (const) More...
 
void connectorDestroy (ConnectorType const &)
 

Related Functions

(Note that these are not member functions.)

template<class MultiConnectorSource , class Target , class A1 >
MultiConnectorSource::ConnectorType & connect (MultiConnectorSource &source, A1 const &a1, Target &target)
 Connect MultiConnector source to arbitrary target. More...
 
template<class Source , class MultiConnectorTarget , class A1 >
MultiConnectorTarget::ConnectorType & connect (Source &source, MultiConnectorTarget &target, A1 const &a1)
 Connect arbitrary source to MultiConnector target. More...
 

Detailed Description

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
class senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >

Multi-Connector management.

This mixin provides a module with support for a runtime configurable number of input or output connectors.

class MyModule
MyModule, senf::ppi::connector::ActiveInput<> >
{
SENF_PPI_MODULE(MyModule);
public:
// ...
private:
void connectorSetup(senf::ppi::connector::ActiveInput & input)
{
route(input, output);
input.onThrottle(&MyModule::doThrottle);
}
// Optional
{
// whatever
}
void doThrottle()
{
// ...
}
MyModule, senf::ppi::connector::ActiveInput<> >;
}
    Using the MultiConnectorMixin consists of
    \li inheriting from MultiConnectorMixin
    \li defining a function \c connectorSetup
    \li declaring the mixin as a friend
    \li optionally defining \c connectorDestroy to be notified when connectors are disconnected

    The MultiConnectorMixin takes several template arguments
    \li the name of the derived class, \a Self_
    \li the type of connector, \a ConnectorType_
    \li an optional \a KeyType_ if a mapping container is required
    \li an optional \a ContainerType_ to replace the default \c boost::ptr_vector or \c
        boost::ptr_map.

Sequence/vector based multi connector mixin

    If no \a KeyType_ is given (or the \a KeyType_ is \c void), the mixin will use a sequence
    container, by default a \c boost::ptr_vector to store the connectors. In this case, new
    connectors will be added to the end of the container. The \c connectorSetup() routine
    however may be used to move the inserted connector to some other location, e.g.
container().insert(begin(), container().pop_back().release());

which will move the new connector from the end to the beginning. If you want to abort adding the new connector, you may throw an exception.

Example:
senf::ppi::module::PriorityJoin

Map based multi connector mixin

    If \a KeyType_ is given (and is not \c void), the mixin will use a mapping container, by
    default a \c boost::ptr_map to store the connectors. The \c connectorSetup() member function
    must return the key value under which the new connector will be stored. The new connector
    will this be written to the container only \e after \c connectorSetup() returns.

    When the returned key is not unique, the new connector will \e replace the old one. If this
    is not what you want, either check for an already existing member and throw an exception in
    \c connectorSetup() or replace the \c boost::ptr_map by a \c boost::ptr_multimap using the
    fourth template argument to MultiConnectorMixin.

    \par "Example:" senf::ppi::module::AnnotationRouter

Connect and additional connectorSetup() arguments

    When connecting to a module using the MultiConnectorMixin, every new connect call will
    allocate a new connector
MyModule muModule;
senf::ppi::connect(someModule, myModule);

Some modules will expect additional arguments to be passed (see below)

MyModule myModule;
senf::ppi::connect(mod1, myModule); // index = 0, see below
senf::ppi::connect(mod2, myModule, 1); // index = 1, see below

To declare these additional arguments, just declare connectorSetup() with those additional arguments:

void connectorSetup(MyModule::ConnectorType & input, int index=0)
{
container().insert(container().begin()+index, container().pop_back().release());
}
    \par "Advanced note:" These additional arguments are always passed by const-reference. If
        you need to pass a non-const reference, declare the \c connectorSetup() argument as
        non-const reference and wrap the real argument using \c boost::ref() (The reason for
        this is known as 'The forwarding problem').

Advanced usage: Managing your own container

    If you need to use a completely different type of container, you can take over the container
    management yourself. To do this, pass \c void as container type and change \c
    connectorSetup() to take an \c std::unique_ptr as argument. \c connectorSetup() must ensure to
    save this connector in some container or throw an exception.

    Implementing \c connectorDestroy now is \e mandatory. The signature is changed to take a
    pointer as argument
class MyModule
MyModule, senf::ppi::connector::ActiveInput<>, void, void >
{
SENF_PPI_MODULE(MyModule);
public:
// ...
private:
void connectorSetup(std::unique_ptr<ConnectorType> conn, unsigned p)
{
if (p>connectors_.size())
throw SomeErrorException();
route(*conn, output);
connectors_.insert(connectors_.begin()+p,conn);
}
void connectorDestroy(ConnectorType const * conn)
{
using boost::lambda::_1;
boost::ptr_vector<ConnectorType>::iterator i (
std::find_if(connectors_.begin(),connectors_.end(), &_1==conn))
if (i != connectors_.end())
connectors_.erase(i);
}
boost::ptr_vector<ConnectorType> connectors_;
};
Warning
You must make absolutely sure the connector does not get deleted when returning normally from connectorSetup(): The connector must be saved somewhere successfully, otherwise your code will break.

Definition at line 241 of file MultiConnectorMixin.hh.

Member Typedef Documentation

◆ ConnectorType

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
typedef ConnectorType_ senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >::ConnectorType

Type of MultiConnector connector.

Definition at line 245 of file MultiConnectorMixin.hh.

◆ ContainerType

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
typedef ContainerType_ senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >::ContainerType
protected

Type of connector container.

Definition at line 248 of file MultiConnectorMixin.hh.

Member Function Documentation

◆ connectorDestroy()

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
void senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >::connectorDestroy ( ConnectorType const &  )
protected

◆ connectors() [1/2]

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
ContainerType_& senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >::connectors ( )
protected

Get connector container.

◆ connectors() [2/2]

template<class Self_, class ConnectorType_, class KeyType_ = void, class ContainerType_ = typename detail::MultiConnectorDefaultContainer<KeyType_, ConnectorType_>::type>
ContainerType_ const& senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, KeyType_, ContainerType_ >::connectors ( ) const
protected

Get connectors container (const)

Friends And Related Function Documentation

◆ connect() [1/2]

template<class MultiConnectorSource , class Target , class A1 >
MultiConnectorSource::ConnectorType & connect ( MultiConnectorSource &  source,
A1 const &  a1,
Target &  target 
)
related

Connect MultiConnector source to arbitrary target.

Additional implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments.

◆ connect() [2/2]

template<class Source , class MultiConnectorTarget , class A1 >
MultiConnectorTarget::ConnectorType & connect ( Source &  source,
MultiConnectorTarget &  target,
A1 const &  a1 
)
related

Connect arbitrary source to MultiConnector target.

Additional implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments.


The documentation for this class was generated from the following file: