//#include "AnnotationRouter.ih"
// Custom includes
+#include "Connectors.hh"
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
notifyRoutes_.push_back(&route);
}
+prefix_ void senf::ppi::connector::ActiveConnector::unregisterRoute(ForwardingRoute & route)
+{
+ NotifyRoutes::iterator i (std::find(notifyRoutes_.begin(), notifyRoutes_.end(), &route));
+ if (i != notifyRoutes_.end())
+ notifyRoutes_.erase(i);
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::InputConnector
// Custom includes
#include <senf/Utils/TypeInfo.hh>
#include <senf/Utils/senfassert.hh>
+#include "Module.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
return peer_;
}
+prefix_ void senf::ppi::connector::Connector::unregisterConnector()
+{
+ if (module_)
+ module_->unregisterConnector(*this);
+}
+
////////////////////////////////////////
// private members
routes_.push_back(&route);
}
+prefix_ void senf::ppi::connector::PassiveConnector::unregisterRoute(ForwardingRoute & route)
+{
+ Routes::iterator i (std::find(routes_.begin(), routes_.end(), &route));
+ if (i != routes_.end())
+ routes_.erase(i);
+}
+
// public members
prefix_ bool senf::ppi::connector::PassiveConnector::nativeThrottled()
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::PassiveConnector
+prefix_ senf::ppi::connector::PassiveConnector::~PassiveConnector()
+{
+ // Must be here and NOT in base so it is called before destructing the routes_ member
+ unregisterConnector();
+}
+
template <class Handler>
prefix_ void senf::ppi::connector::PassiveConnector::onRequest(Handler handler)
{
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
+prefix_ senf::ppi::connector::ActiveConnector::~ActiveConnector()
+{
+ // Must be here and NOT in base so it is called before destructing the routes_ member
+ unregisterConnector();
+}
+
template <class Handler>
prefix_ void senf::ppi::connector::ActiveConnector::onThrottle(Handler handler)
{
void trace(Packet const & p, char const * label);
void throttleTrace(char const * label, char const * type);
+
+ void unregisterConnector();
private:
virtual std::type_info const & packetTypeID();
: public virtual Connector
{
public:
+ ~PassiveConnector();
+
template <class Handler>
void onRequest(Handler handler);///< Register I/O event handler
/**< The registered handler will be called, whenever packets
// called by ForwardingRoute to register a new route
void registerRoute(ForwardingRoute & route);
+ void unregisterRoute(ForwardingRoute & route);
typedef ppi::detail::Callback<>::type Callback;
Callback callback_;
{
typedef ppi::detail::Callback<>::type Callback;
public:
+ ~ActiveConnector();
+
template <class Handler>
void onThrottle(Handler handler); ///< Register throttle notification handler
/**< The handler register here will be called, whenever a
// called by ForwardingRoute to register a new route
void registerRoute(ForwardingRoute & route);
+ void unregisterRoute(ForwardingRoute & route);
Callback throttleCallback_;
Callback unthrottleCallback_;
// Custom includes
#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
//#include "EventManager.mpp"
#define prefix_
prefix_ void senf::ppi::EventManager::destroyModule(module::Module & module)
{
using boost::lambda::_1;
+ namespace l = boost::lambda;
- // boost::ptr_vector::erase(f,l) asserts !empty() .. why ??
- if (!registrations_.empty())
- registrations_.erase(
- std::remove_if(registrations_.begin(), registrations_.end(),
- ((&_1) ->* & detail::EventBindingBase::module_) == & module),
- registrations_.end());
+ registrations_.erase_if(l::bind(&detail::EventBindingBase::module_,_1) == &module);
+}
+
+prefix_ void senf::ppi::EventManager::destroyEvent(EventDescriptor & event)
+{
+ using boost::lambda::_1;
+ namespace l = boost::lambda;
+
+ SENF_ASSERT(
+ std::find_if(registrations_.begin(), registrations_.end(),
+ l::bind(&detail::EventBindingBase::descriptor_,_1) == &event)
+ == registrations_.end());
}
///////////////////////////////cc.e////////////////////////////////////////
Descriptor & descriptor);
void destroyModule(module::Module & module);
+ void destroyEvent(EventDescriptor & event);
typedef boost::ptr_vector<detail::EventBindingBase> EventRegistrations;
EventRegistrations registrations_;
friend class detail::EventBindingBase;
friend class module::Module;
+ friend class EventDescriptor;
};
}}
// Custom includes
#include "Route.hh"
+#include "EventManager.hh"
//#include "Events.mpp"
#define prefix_
///////////////////////////////////////////////////////////////////////////
// senf::ppi::EventDescriptor
+prefix_ senf::ppi::EventDescriptor::~EventDescriptor()
+{
+ if (binding_)
+ binding_->manager().destroyEvent(*this);
+}
+
prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle()
{
Routes::const_iterator i (routes_.begin());
// Custom includes
#include <senf/Utils/senfassert.hh>
+#include <senf/PPI/detail/EventBinding.hh>
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::ppi::EventDescriptor
-prefix_ senf::ppi::EventDescriptor::~EventDescriptor()
-{}
-
prefix_ bool senf::ppi::EventDescriptor::enabled()
{
return enabled_;
routes_.push_back(&route);
}
+prefix_ void senf::ppi::EventDescriptor::unregisterRoute(ForwardingRoute & route)
+{
+ Routes::iterator i (std::find(routes_.begin(), routes_.end(), &route));
+ if (i != routes_.end())
+ routes_.erase(i);
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
namespace senf {
namespace ppi {
+
+ namespace detail { class EventBindingBase; }
/** \defgroup event_group Events
void notifyUnthrottle();
void registerRoute(ForwardingRoute & route);
+ void unregisterRoute(ForwardingRoute & route);
bool enabled_;
bool throttled_;
typedef std::vector<ForwardingRoute*> Routes;
Routes routes_;
+ detail::EventBindingBase * binding_;
+
friend class ForwardingRoute;
+ friend class detail::EventBindingBase;
};
/** \brief Internal: Callback forwarders
#include "Connectors.hh"
#include "EventManager.hh"
#include "ModuleManager.hh"
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <algorithm>
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
}
}
+prefix_ void senf::ppi::module::Module::unregisterConnector(connector::Connector & connector)
+{
+ ConnectorRegistry::iterator i (std::find(connectorRegistry_.begin(), connectorRegistry_.end(),
+ &connector));
+ if (i != connectorRegistry_.end())
+ connectorRegistry_.erase(i);
+
+ routes_.erase_if(boost::bind(&RouteBase::hasConnector, _1, boost::cref(connector)));
+}
+
+prefix_ void senf::ppi::module::Module::unregisterEvent(EventDescriptor & event)
+{
+ routes_.erase_if(boost::bind(&RouteBase::hasEvent, _1, boost::cref(event)));
+}
+
prefix_ senf::ppi::RouteBase &
senf::ppi::module::Module::addRoute(std::auto_ptr<RouteBase> route)
{
prefix_ senf::ppi::module::Module::~Module()
{
+ SENF_ASSERT(connectorRegistry_.empty());
+ SENF_ASSERT(routes_.empty());
+
moduleManager().unregisterModule(*this);
}
namespace senf {
namespace ppi {
+
+ namespace detail { class EventBindingBase; }
+
namespace module {
/** \namespace senf::ppi::module
ModuleManager & moduleManager() const;
void registerConnector(connector::Connector & connector);
+ void unregisterConnector(connector::Connector & connector);
+ void unregisterEvent(EventDescriptor & event);
+
RouteBase & addRoute(std::auto_ptr<RouteBase> route);
typedef std::vector<connector::Connector *> ConnectorRegistry;
template <class Source, class Target>
friend class detail::RouteHelper;
friend class senf::ppi::ModuleManager;
+ friend class connector::Connector;
+ friend class senf::ppi::detail::EventBindingBase;
};
/** \brief Define PPI Module
prefix_ senf::ppi::RouteBase::~RouteBase()
{}
+prefix_ bool senf::ppi::RouteBase::hasConnector(connector::Connector const & conn)
+ const
+{
+ return v_hasConnector(conn);
+}
+
+prefix_ bool senf::ppi::RouteBase::hasEvent(EventDescriptor const & event)
+ const
+{
+ return v_hasEvent(event);
+}
+
////////////////////////////////////////
// protected members
}
template <class T>
+prefix_ void senf::ppi::ForwardingRoute::unregisterRoute(T & ob)
+{
+ ob.unregisterRoute(*this);
+}
+
+template <class T>
prefix_ void senf::ppi::ForwardingRoute::notifyThrottle(T & ob)
{
ob.notifyThrottle();
: Base(module), source_(&source), target_(&target)
{}
+////////////////////////////////////////
+// private members
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+v_hasConnector(connector::Connector const & conn)
+ const
+{
+ return isSame(conn, source()) || isSame(conn, target());
+}
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+v_hasEvent(EventDescriptor const & event)
+ const
+{
+ return isSame(event, source()) || isSame(event, target());
+}
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+isSame(connector::Connector const & conn, connector::Connector const & other)
+ const
+{
+ return &conn == &other;
+}
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+isSame(connector::Connector const & conn, EventDescriptor const & other)
+ const
+{
+ return false;
+}
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+isSame(EventDescriptor const & event, connector::Connector const & other)
+ const
+{
+ return false;
+}
+
+template <class Source, class Target, class Base>
+prefix_ bool senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::
+isSame(EventDescriptor const & event, EventDescriptor const & other)
+ const
+{
+ return &event == &other;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::detail::ForwardingRouteImplementation<Source,Target>
registerRoute(target);
}
+template <class Source, class Target>
+prefix_
+senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
+~ForwardingRouteImplementation()
+{
+ unregisterRoute(this->source());
+ unregisterRoute(this->target());
+}
+
////////////////////////////////////////
// private members
class is internal and not documented. */
#endif
+ bool hasConnector(connector::Connector const & conn) const;
+ ///< \c true, if route has connector \a conn
+ bool hasEvent(EventDescriptor const & event) const;
+ ///< \c true, if route has event \a event
+
protected:
RouteBase(module::Module & module);
private:
+ virtual bool v_hasConnector(connector::Connector const & conn) const = 0;
+ virtual bool v_hasEvent(EventDescriptor const & event) const = 0;
+
module::Module * module_;
};
// Called to register this route with the connectors forwarding information base
template <class T> void registerRoute(T & ob);
+ template <class T> void unregisterRoute(T & ob);
template <class T> void notifyThrottle(T & ob);
template <class T> void notifyUnthrottle(T & ob);
BaseRouteImplementation(module::Module & module, Source & source, Target & target);
private:
+ bool v_hasConnector(connector::Connector const & conn) const;
+ bool v_hasEvent(EventDescriptor const & event) const;
+
+ bool isSame(connector::Connector const & conn, connector::Connector const & other) const;
+ bool isSame(connector::Connector const & conn, EventDescriptor const & other) const;
+ bool isSame(EventDescriptor const & event, connector::Connector const & other) const;
+ bool isSame(EventDescriptor const & event, EventDescriptor const & other) const;
+
Source * source_;
Target * target_;
};
protected:
ForwardingRouteImplementation(module::Module & module, Source & source, Target & target);
+ ~ForwardingRouteImplementation();
private:
// send a throttle/unthrottle notification only if the second argument is a 'true' type
// Custom includes
#include <senf/PPI/EventManager.hh>
+#include <senf/PPI/Module.hh>
//#include "EventBinding.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
+prefix_ senf::ppi::detail::EventBindingBase::~EventBindingBase()
+{
+ descriptor_->enabled(false);
+ module().unregisterEvent(*descriptor_);
+ descriptor_->binding_ = 0;
+}
+
prefix_ void senf::ppi::detail::EventBindingBase::eventTime(ClockService::clock_type time)
{
// It's hard to make this inline because of a circular header dependency ...
///////////////////////////////////////////////////////////////////////////
// senf::ppi::detail::EventBindingBase
-prefix_ senf::ppi::detail::EventBindingBase::~EventBindingBase()
-{
- descriptor_->enabled(false);
-}
-
prefix_ senf::ppi::EventManager & senf::ppi::detail::EventBindingBase::manager()
const
{
module::Module & module,
EventDescriptor & descriptor)
: manager_(&manager), module_(&module), descriptor_(&descriptor)
-{}
+{
+ descriptor_->binding_ = this;
+}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
EventDescriptor * descriptor_;
friend class senf::ppi::EventManager;
+ friend class senf::ppi::EventDescriptor;
};
/** \brief Internal: Callback forwarders