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

Multi-Connector management. More...

#include <senf/PPI/MultiConnectorMixin.hh>

List of all members.


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
    : public senf::ppi::module::Module,
      public senf::ppi::module::MultiConnectorMixin<
          MyModule, senf::ppi::connector::ActiveInput<> >
{
    SENF_PPI_MODULE(MyModule);
public:
    senf::ppi::connector::PassiveOutput<> output;

    // ...

private:
    void connectorSetup(senf::ppi::connector::ActiveInput & input)
    {
        route(input, output);
        input.onThrottle(&MyModule::doThrottle);
    }

    // Optional
    void connectorDestroy(senf::ppi::connector::ActiveInput const & input)
    {
         //  whatever
    }

    void doThrottle()
    {
        // ...
    }

    friend class senf::ppi::module::MultiConnectorMixin<
        MyModule, senf::ppi::connector::ActiveInput<> >;
}

Using the MultiConnectorMixin consists of

  • inheriting from MultiConnectorMixin
  • defining a function connectorSetup
  • declaring the mixin as a friend
  • optionally defining connectorDestroy to be notified when connectors are disconnected
The MultiConnectorMixin takes several template arguments
  • the name of the derived class, Self_
  • the type of connector, ConnectorType_
  • an optional KeyType_ if a mapping container is required
  • an optional ContainerType_ to replace the default boost::ptr_vector or boost::ptr_map.

Sequence/vector based multi connector mixin

If no KeyType_ is given (or the KeyType_ is void), the mixin will use a sequence container, by default a boost::ptr_vector to store the connectors. In this case, new connectors will be added to the end of the container. The 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 KeyType_ is given (and is not void), the mixin will use a mapping container, by default a boost::ptr_map to store the connectors. The 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 after connectorSetup() returns.

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

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());
}
Advanced note:
These additional arguments are always passed by const-reference. If you need to pass a non-const reference, declare the connectorSetup() argument as non-const reference and wrap the real argument using 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 void as container type and change connectorSetup() to take an std::auto_ptr as argument. connectorSetup() must ensure to save this connector in some container or throw an exception.

Implementing connectorDestroy now is mandatory. The signature is changed to take a pointer as argument

class MyModule
    : public senf::ppi::module::Module,
      public senf::ppi::module::MultiConnectorMixin<
          MyModule, senf::ppi::connector::ActiveInput<>, void, void >
{
    SENF_PPI_MODULE(MyModule);
public:
    // ...

private:
    void connectorSetup(std::auto_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 255 of file MultiConnectorMixin.hh.


Public Types

typedef ConnectorType_  ConnectorType
  Type of MultiConnector connector.

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.
template<class Source , class MultiConnectorTarget , class A1 >
MultiConnectorTarget::ConnectorType &  connect (Source &source, MultiConnectorTarget &target, A1 const &a1)
  Connect arbitrary source to MultiConnector target.

Protected Types

typedef ContainerType_  ContainerType
  Type of connector container.

Protected Member Functions

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

Member Typedef Documentation

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 259 of file MultiConnectorMixin.hh.

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 262 of file MultiConnectorMixin.hh.


Member Function Documentation

template<class Self_ , class ConnectorType_ , class ContainerType_ >
void senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, ContainerType_ >::
connectorDestroy ( ConnectorType const &  )

Definition at line 65 of file MultiConnectorMixin.cti.

template<class Self_ , class ConnectorType_ , class ContainerType_ >
ContainerType_ const & senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, ContainerType_ >::
connectors ()

Get connectors container (const).

Definition at line 56 of file MultiConnectorMixin.cti.

template<class Self_ , class ConnectorType_ , class ContainerType_ >
ContainerType_ & senf::ppi::module::MultiConnectorMixin< Self_, ConnectorType_, ContainerType_ >::
connectors ()

Get connector container.

Definition at line 48 of file MultiConnectorMixin.cti.


Friends And Related Function Documentation

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

Connect arbitrary source to MultiConnector target.

Additional implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments.

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

Connect MultiConnector source to arbitrary target.

Additional implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments.


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