From: g0dil Date: Fri, 26 Jun 2009 12:42:07 +0000 (+0000) Subject: PPI: Implement DynamicConnectorMixin X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=d9943801e27b7f775ca971057fd3a024aab38ac1;p=senf.git PPI: Implement DynamicConnectorMixin PPI: Update all modules utilizing dynamic connectors to utilize the mixin git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1242 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/PPI/AnnotationRouter.ct b/PPI/AnnotationRouter.ct index bef2f9c..6231164 100644 --- a/PPI/AnnotationRouter.ct +++ b/PPI/AnnotationRouter.ct @@ -39,30 +39,22 @@ prefix_ senf::ppi::module::AnnotationRouter::AnnotationRouter() } template -prefix_ senf::ppi::connector::ActiveOutput<> & -senf::ppi::module::AnnotationRouter::newOutput(AnnotationType const & key) +prefix_ AnnotationType senf::ppi::module::AnnotationRouter:: +connectorSetup(connector::ActiveOutput<> & conn, AnnotationType const & key) { - if (outputs_.find(key) != outputs_.end()) + if (this->connectors().find(key) != this->connectors().end()) throw DuplicateKeyException(key); - // key must not be const ... has something to do with exception guarantees ?? - // From boost 1.34.0 on we can use auto_ptr which we really should for exception safety - // but this doesn't work with boost 1.33.1 :-( -#if BOOST_VERSION >= 103400 - return *outputs_.insert(key, - std::auto_ptr >( - new connector::ActiveOutput<>())).first->second; -#else - AnnotationType k (key); - return *outputs_.insert(k, new connector::ActiveOutput<>()).first; -#endif + route(input, conn); + return key; } template prefix_ void senf::ppi::module::AnnotationRouter::request() { Packet p (input()); - typename Outputs::iterator i (outputs_.find(p.annotation())); - if (i == outputs_.end()) + typename AnnotationRouter::DynamicConnectorContainer::iterator i ( + this->connectors().find(p.annotation())); + if (i == this->connectors().end()) defaultOutput(p); else { #if BOOST_VERSION >= 103400 diff --git a/PPI/AnnotationRouter.hh b/PPI/AnnotationRouter.hh index 705eb8d..7badaaf 100644 --- a/PPI/AnnotationRouter.hh +++ b/PPI/AnnotationRouter.hh @@ -31,6 +31,7 @@ #include "../Utils/String.hh" #include "Module.hh" #include "Connectors.hh" +#include "DynamicConnectorMixin.hh" //#include "AnnotationRouter.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -93,7 +94,11 @@ namespace module { from the container */ template - class AnnotationRouter : public Module + class AnnotationRouter + : public Module, + public DynamicConnectorMixin< AnnotationRouter, + connector::ActiveOutput<>, + AnnotationType > { SENF_PPI_MODULE(AnnotationRouter); public: @@ -108,39 +113,23 @@ namespace module { { append( senf::str(key)); } }; private: - connector::ActiveOutput<> & newOutput(AnnotationType const & key); - -#ifndef DOXYGEN - // I didn't get template friend functions to work ... - public: -#endif - template - connector::GenericActiveOutput & connect(Target & target, AnnotationType const & key); - - private: + AnnotationType connectorSetup(connector::ActiveOutput<> & conn, AnnotationType const & key); void request(); typedef boost::ptr_map > Outputs; Outputs outputs_; - }; -} - -#ifndef DOXYGEN - - template - connector::GenericActiveOutput & connect( - module::AnnotationRouter & source, Target & target, - ArgType const & key); - -#endif + friend class DynamicConnectorMixin< AnnotationRouter, + connector::ActiveOutput<>, + AnnotationType >; + }; -}} +}}} ///////////////////////////////hh.e//////////////////////////////////////// //#include "AnnotationRouter.cci" #include "AnnotationRouter.ct" -#include "AnnotationRouter.cti" +//#include "AnnotationRouter.cti" #endif diff --git a/PPI/Duplicators.cc b/PPI/Duplicators.cc index f62679d..b6dd077 100644 --- a/PPI/Duplicators.cc +++ b/PPI/Duplicators.cc @@ -32,22 +32,17 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ senf::ppi::connector::ActiveOutput<> & -senf::ppi::module::ActiveDuplicator::newOutput() +prefix_ void +senf::ppi::module::ActiveDuplicator::connectorSetup(ActiveDuplicator::DynamicConnector & conn) { - outputs_.push_back(new connector::ActiveOutput<>()); - connector::ActiveOutput<> & output (outputs_.back()); - - route(input, output); - - return output; + route(input, conn); } prefix_ void senf::ppi::module::ActiveDuplicator::request() { Packet p (input()); - Outputs::iterator i (outputs_.begin()); - Outputs::iterator const i_end (outputs_.end()); + ActiveDuplicator::ConnectorContainer::iterator i (connectors().begin()); + ActiveDuplicator::ConnectorContainer::iterator const i_end (connectors().end()); for (; i != i_end; ++i) (*i)(p); } diff --git a/PPI/Duplicators.hh b/PPI/Duplicators.hh index f5ea389..fea0a46 100644 --- a/PPI/Duplicators.hh +++ b/PPI/Duplicators.hh @@ -31,20 +31,13 @@ #include "predecl.hh" #include "Connectors.hh" #include "Module.hh" +#include "DynamicConnectorMixin.hh" //#include "Duplicators.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { namespace ppi { - -#ifndef DOXYGEN - - template - connector::GenericActiveOutput & connect(module::ActiveDuplicator & source, Target & target); - -#endif - namespace module { /** \brief Copy every incoming packet to each output @@ -65,7 +58,8 @@ namespace module { \ingroup routing_modules */ class ActiveDuplicator - : public Module + : public Module, + public DynamicConnectorMixin > { SENF_PPI_MODULE(ActiveDuplicator); public: @@ -74,19 +68,10 @@ namespace module { ActiveDuplicator(); private: - connector::ActiveOutput<> & newOutput(); - -#ifndef DOXYGEN - public: -#endif - template - connector::GenericActiveOutput & connect(Target & target); - - private: + void connectorSetup(ActiveDuplicator::DynamicConnector & conn); void request(); - typedef boost::ptr_vector > Outputs; - Outputs outputs_; + friend class DynamicConnectorMixin >; }; }}} @@ -96,7 +81,7 @@ namespace module { ///////////////////////////////hh.e//////////////////////////////////////// #include "Duplicators.cci" //#include "Duplicators.ct" -#include "Duplicators.cti" +//#include "Duplicators.cti" #endif diff --git a/PPI/Duplicators.cti b/PPI/DynamicConnectorMixin.cti similarity index 64% rename from PPI/Duplicators.cti rename to PPI/DynamicConnectorMixin.cti index fb9e74f..97742b2 100644 --- a/PPI/Duplicators.cti +++ b/PPI/DynamicConnectorMixin.cti @@ -21,32 +21,35 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief Duplicators inline template implementation */ + \brief DynamicConnectorMixin inline template implementation */ -//#include "Duplicators.ih" +//#include "DynamicConnectorMixin.ih" // Custom includes -#include "Setup.hh" #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// -template -prefix_ senf::ppi::connector::GenericActiveOutput & -senf::ppi::connect(module::ActiveDuplicator & source, Target & target) +template +prefix_ ContainerType & +senf::ppi::module::DynamicConnectorMixin::connectors() { - return source.connect(target); + return connectors_; } -template -prefix_ senf::ppi::connector::GenericActiveOutput & -senf::ppi::module::ActiveDuplicator::connect(Target & target) +template +prefix_ ContainerType & +senf::ppi::module::DynamicConnectorMixin::connectors() { - connector::GenericActiveOutput & output (newOutput()); - ppi::connect(output, target); - return output; + return connectors_; } +#define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ + 0, \ + SENF_DYNAMIC_CONNECTOR_MAX_ARGS, \ + SENF_ABSOLUTE_INCLUDE_PATH(PPI/DynamicConnectorMixin.mpp), \ + 3 )) +#include BOOST_PP_ITERATE() ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/PPI/DynamicConnectorMixin.hh b/PPI/DynamicConnectorMixin.hh new file mode 100644 index 0000000..996dc05 --- /dev/null +++ b/PPI/DynamicConnectorMixin.hh @@ -0,0 +1,160 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief DynamicConnectorMixin public header */ + +#ifndef HH_SENF_PPI_DynamicConnectorMixin_ +#define HH_SENF_PPI_DynamicConnectorMixin_ 1 + +// Custom includes +#include "../config.hh" +#include +#include +#include +#include "Connectors.hh" +#include "Setup.hh" + +#include "DynamicConnectorMixin.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +#ifndef SENF_DYNAMIC_CONNECTOR_MAX_ARGS +#define SENF_DYNAMIC_CONNECTOR_MAX_ARGS 3 +#endif + +namespace senf { +namespace ppi { + +# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ + 0, \ + SENF_DYNAMIC_CONNECTOR_MAX_ARGS, \ + SENF_ABSOLUTE_INCLUDE_PATH(PPI/DynamicConnectorMixin.mpp), \ + 2 )) +# include BOOST_PP_ITERATE() + +namespace module { + +namespace detail { + template + struct DefaultDynamicContainer + { typedef boost::ptr_map type; }; + + template + struct DefaultDynamicContainer + { typedef boost::ptr_vector type; }; + + template + struct DynamicDisableType + : public boost::mpl::if_< + boost::is_base_of, + ppi::detail::DisableStandardInput, ppi::detail::DisableStandardOutput > + {}; +} + + /** \brief Dynamic connector management + + Provide modules with support for dynamic connectors. + + \li A module might have dynamic input or output connectors + \li Creating a new connection might take an argument + \li Connectors are stored either in a vector or a map + + Workflow: + \li Connectors are created by the helper. + \li Connector is passed to Self::connectorSetup. This returns either void or the map + key. connectorSetup must setup internal routing and callbacks. + \li Connector inserted into container. + + connectorSetup may take additional arguments besides reference to connector. These arguments + are taken from the trailing ppi::connect call arguments. + + The list manager will insert the new connector at the end of the list BEFORE calling + connetorSetup. This allows the setup routine to manipulate the position. + */ + template ::type> + class DynamicConnectorMixin + : private detail::DynamicDisableType::type + { + public: + typedef ConnectorType DynamicConnector; + + protected: + typedef ContainerType DynamicConnectorContainer; + ContainerType & connectors(); + + private: +# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ + 0, \ + SENF_DYNAMIC_CONNECTOR_MAX_ARGS, \ + SENF_ABSOLUTE_INCLUDE_PATH(PPI/DynamicConnectorMixin.mpp), \ + 1 )) +# include BOOST_PP_ITERATE() + + ContainerType connectors_; + }; + + template + class DynamicConnectorMixin + : private detail::DynamicDisableType::type + { + public: + typedef ConnectorType DynamicConnector; + + protected: + typedef ContainerType ConnectorContainer; + ContainerType & connectors(); + + private: +# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ + 0, \ + SENF_DYNAMIC_CONNECTOR_MAX_ARGS, \ + SENF_ABSOLUTE_INCLUDE_PATH(PPI/DynamicConnectorMixin.mpp), \ + 1 )) +# include BOOST_PP_ITERATE() + + ContainerType connectors_; + }; + +}}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "DynamicConnectorMixin.cci" +//#include "DynamicConnectorMixin.ct" +#include "DynamicConnectorMixin.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/PPI/DynamicConnectorMixin.mpp b/PPI/DynamicConnectorMixin.mpp new file mode 100644 index 0000000..19d6b8c --- /dev/null +++ b/PPI/DynamicConnectorMixin.mpp @@ -0,0 +1,188 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief DynamicConnectorMixin Boost.Preprocesser external iteration include */ + +#if !BOOST_PP_IS_ITERATING && !defined(MPP_SENF_PPI_DynamicConnectorMixin_) +#define MPP_SENF_PPI_DynamicConnectorMixin_ 1 + +// Custom includes +#include +#include +#include +#include +#include +#include +#include +#include + +// ///////////////////////////mpp.p//////////////////////////////////////// +#elif BOOST_PP_IS_ITERATING // //////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// +// Local Macros + +#define mpp_TplParams() \ + BOOST_PP_IF( \ + BOOST_PP_ITERATION(), \ + mpp_TplParams_, \ + BOOST_PP_EMPTY)() +#define mpp_TplParams_() \ + template + +#define mpp_TplParamsKomma() \ + BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class A) +#define mpp_FnParams() \ + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a) +#define mpp_FnParamsKomma() \ + BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a) +#define mpp_CallParams() \ + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a) +#define mpp_CallParamsKomma() \ + BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), a) + +// //////////////////////////////////////////////////////////////////////// +#if BOOST_PP_ITERATION_FLAGS()==1 // ////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// +// DynamicConnectorMixin member declaration + +mpp_TplParams() +ConnectorType & newConnector( mpp_FnParams() ); + +template +friend typename boost::enable_if< + boost::is_base_of, + typename Source::DynamicConnector & >::type + senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()); + +template +friend typename boost::enable_if< + boost::is_base_of, + typename Target::DynamicConnector & >::type + senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()); + +// //////////////////////////////////////////////////////////////////////// +#elif BOOST_PP_ITERATION_FLAGS()==2 // //////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// +// senf::ppi namespace member declaration + +template +typename boost::enable_if< + boost::is_base_of, + typename Source::DynamicConnector & >::type +connect(Source & source, Target & target mpp_FnParamsKomma()); + +template +typename boost::enable_if< + boost::is_base_of, + typename Target::DynamicConnector & >::type +connect(Source & source, Target & target mpp_FnParamsKomma()); + +// //////////////////////////////////////////////////////////////////////// +#elif BOOST_PP_ITERATION_FLAGS()==3 // //////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// +// Implementation + +template +mpp_TplParams() +prefix_ ConnectorType & +senf::ppi::module::DynamicConnectorMixin:: +newConnector(mpp_FnParams()) +{ + std::auto_ptr conn (new ConnectorType); + KeyType key (static_cast(this)->connectorSetup(*conn mpp_CallParamsKomma())); + return * connectors_.insert(key, conn).first->second; +} + +template +mpp_TplParams() +prefix_ ConnectorType & +senf::ppi::module::DynamicConnectorMixin:: +newConnector(mpp_FnParams()) +{ + connectors_.push_back(new ConnectorType); + ConnectorType & conn (connectors_.back()); + try { static_cast(this)->connectorSetup(conn mpp_CallParamsKomma()); } + catch (...) { connectors_.pop_back(); throw; } + return conn; +} + +template +typename boost::enable_if< + boost::is_base_of, + typename Source::DynamicConnector & >::type +senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()) +{ + connect(source.newConnector(mpp_CallParams()), target); +} + +template +typename boost::enable_if< + boost::is_base_of, + typename Target::DynamicConnector & >::type +senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()) +{ + connect(source, target.newConnector(mpp_CallParams())); +} + +// //////////////////////////////////////////////////////////////////////// +#endif // ///////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// +// Undefine local Macros + +#undef mpp_CallParamsKomma +#undef mpp_CallParams +#undef mpp_FnParamsKomma +#undef mpp_FnParams +#undef mpp_TplParamsKomma +#undef mpp_TplParams_ +#undef mpp_TplParams + +// //////////////////////////////////////////////////////////////////////// +/* + (save-excursion (re-search-backward "^// Undefine local Macros") + (forward-line 1) (delete-region (point) (progn (search-forward + "// ////") (forward-line -1) (point))) (insert "\n") (let ((b (point)) + (e (progn (insert (save-excursion (re-search-backward + "^// Local Macros") (search-forward "#define") (beginning-of-line) + (buffer-substring (point) (progn (search-forward "// ////") + (search-backward "#define") (forward-line 1) (point))))) (point)))) + (reverse-region b e) (shell-command-on-region b e "grep -F '#define'" nil + t) (goto-char b) (while (looking-at "#define") (delete-char 7) (insert + "#undef") (skip-chars-forward " ") (re-search-forward "[^a-zA-Z_]") + (delete-region (1- (point)) (progn (end-of-line) (point))) (forward-line + 1)))) +*/ +// //////////////////////////////////////////////////////////////////////// +#endif // ///////////////////////////////////////////////////////////////// +// ///////////////////////////mpp.e//////////////////////////////////////// + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/PPI/AnnotationRouter.cti b/PPI/DynamicConnectorMixin.test.cc similarity index 53% rename from PPI/AnnotationRouter.cti rename to PPI/DynamicConnectorMixin.test.cc index d61468c..9eb5c3d 100644 --- a/PPI/AnnotationRouter.cti +++ b/PPI/DynamicConnectorMixin.test.cc @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2008 +// Copyright (C) 2009 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund @@ -21,41 +21,24 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief AnnotationRouter inline template implementation */ + \brief DynamicConnectorMixin.test unit tests */ -//#include "AnnotationRouter.ih" +//#include "DynamicConnectorMixin.test.hh" +//#include "DynamicConnectorMixin.test.ih" // Custom includes -#include "Setup.hh" +#include "DynamicConnectorMixin.hh" -#define prefix_ inline -///////////////////////////////cti.p/////////////////////////////////////// +#include "../Utils/auto_unit_test.hh" +#include -template -template -prefix_ senf::ppi::connector::GenericActiveOutput & -senf::ppi::module::AnnotationRouter::connect(Target & target, - AnnotationType const & key) -{ - connector::GenericActiveOutput & output (newOutput(key)); - route(input, output); - ppi::connect(output, target); - return output; -} +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// -#ifndef DOXYGEN +BOOST_AUTO_UNIT_TEST(dynamicConnectorMixin) +{} -template -prefix_ senf::ppi::connector::GenericActiveOutput & -senf::ppi::connect(module::AnnotationRouter & source, Target & target, - ArgType const & key) -{ - return source.connect(target, AnnotationType(key)); -} - -#endif - -///////////////////////////////cti.e/////////////////////////////////////// +///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/PPI/Jack.hh b/PPI/Jack.hh index 52c6b82..a47d15d 100644 --- a/PPI/Jack.hh +++ b/PPI/Jack.hh @@ -30,6 +30,7 @@ #include #include #include "Connectors.hh" +#include "Setup.hh" //#include "Jack.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -41,7 +42,7 @@ namespace connector { /** \brief Connector Jack base class \see \ref ppi_jacks */ class Jack - : private boost::noncopyable + : private boost::noncopyable, private ppi::detail::DisableStandardConnect {}; /** \brief Jack referencing an ActiveInput diff --git a/PPI/Joins.cc b/PPI/Joins.cc index b8ce2d6..2ecccf3 100644 --- a/PPI/Joins.cc +++ b/PPI/Joins.cc @@ -42,15 +42,10 @@ //////////////////////////////////////// // private members -prefix_ senf::ppi::connector::PassiveInput<> & senf::ppi::module::PassiveJoin::newInput() +prefix_ void senf::ppi::module::PassiveJoin::connectorSetup(connector::PassiveInput<> & conn) { - inputs_.push_back(new connector::PassiveInput<>()); - connector::PassiveInput<> & input (inputs_.back()); - - noroute(input); - input.onRequest(boost::bind(&PassiveJoin::request,this,boost::ref(input))); - - return input; + noroute(conn); + conn.onRequest(boost::bind(&PassiveJoin::request,this,boost::ref(conn))); } prefix_ void senf::ppi::module::PassiveJoin::request(connector::GenericPassiveInput & input) @@ -62,7 +57,7 @@ prefix_ void senf::ppi::module::PassiveJoin::onThrottle() { using boost::lambda::_1; using boost::lambda::bind; - std::for_each(inputs_.begin(), inputs_.end(), + std::for_each(connectors().begin(), connectors().end(), bind(&connector::GenericPassiveInput::throttle, _1)); } @@ -70,7 +65,7 @@ prefix_ void senf::ppi::module::PassiveJoin::onUnthrottle() { using boost::lambda::_1; using boost::lambda::bind; - std::for_each(inputs_.begin(), inputs_.end(), + std::for_each(connectors().begin(), connectors().end(), bind(&connector::GenericPassiveInput::unthrottle, _1)); } @@ -80,41 +75,40 @@ prefix_ void senf::ppi::module::PassiveJoin::onUnthrottle() //////////////////////////////////////// // private members -prefix_ senf::ppi::connector::ActiveInput<> & -senf::ppi::module::PriorityJoin::newInput(int priority) +prefix_ void +senf::ppi::module::PriorityJoin::connectorSetup(PriorityJoin::DynamicConnector & conn, + int priority) { - if (priority > int(inputs_.size())) - priority = inputs_.size(); - else if (priority < 0) { - priority = inputs_.size() + priority + 1; + noroute(conn); + conn.onThrottle(&PriorityJoin::onThrottle); + conn.onUnthrottle(&PriorityJoin::onUnthrottle); + + if (priority < 0) { + priority = connectors().size() + priority; if (priority < 0) priority = 0; } - - connector::ActiveInput<> & input ( - *inputs_.insert(inputs_.begin()+priority, new connector::ActiveInput<>())); - - noroute(input); - input.onThrottle(&PriorityJoin::onThrottle); - input.onUnthrottle(&PriorityJoin::onUnthrottle); - - return input; + if (priority >= int(connectors().size())-1) + return; + + connectors().insert(connectors().begin()+priority, connectors().pop_back().release()); } prefix_ void senf::ppi::module::PriorityJoin::request() { using boost::lambda::_1; using boost::lambda::bind; - Inputs::iterator i (std::find_if(inputs_.begin(), inputs_.end(), - ! bind(&connector::GenericActiveInput::throttled, _1))); - if (i != inputs_.end()) + PriorityJoin::ConnectorContainer::iterator i ( + std::find_if(connectors().begin(), connectors().end(), + ! bind(&connector::GenericActiveInput::throttled, _1))); + if (i != connectors().end()) output((*i)()); } prefix_ void senf::ppi::module::PriorityJoin::onThrottle() { - if (std::find_if(inputs_.begin(), inputs_.end(), - ! bind(&connector::GenericActiveInput::throttled, _1)) == inputs_.end()) + if (std::find_if(connectors().begin(), connectors().end(), + ! bind(&connector::GenericActiveInput::throttled, _1)) == connectors().end()) output.throttle(); } diff --git a/PPI/Joins.cti b/PPI/Joins.cti deleted file mode 100644 index 1e77d16..0000000 --- a/PPI/Joins.cti +++ /dev/null @@ -1,91 +0,0 @@ -// $Id$ -// -// Copyright (C) 2007 -// Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY -// Stefan Bund -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief Joins inline template implementation */ - -//#include "Joins.ih" - -// Custom includes -#include "Setup.hh" - -#define prefix_ inline -///////////////////////////////cti.p/////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////// -// senf::ppi::module::PassiveJoin - -template -prefix_ senf::ppi::connector::GenericPassiveInput & -senf::ppi::module::PassiveJoin::connect(Source & source) -{ - connector::GenericPassiveInput & input (newInput()); - ppi::connect(source,input); - return input; -} - -/////////////////////////////////////////////////////////////////////////// -// senf::ppi::module::PriorityJoin - -template -prefix_ senf::ppi::connector::GenericActiveInput & -senf::ppi::module::PriorityJoin::connect(Source & source, int priority) -{ - connector::GenericActiveInput & input (newInput(priority)); - ppi::connect(source,input); - return input; -} - -/////////////////////////////////////////////////////////////////////////// -// namespace members - -#ifndef DOXYGEN - -template -prefix_ senf::ppi::connector::GenericPassiveInput & -senf::ppi::connect(Source & source, module::PassiveJoin & target) -{ - return target.connect(source); -} - -template -prefix_ senf::ppi::connector::GenericActiveInput & -senf::ppi::connect(Source & source, module::PriorityJoin & target, int priority) -{ - return target.connect(source, priority); -} - -#endif - -///////////////////////////////cti.e/////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// comment-column: 40 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// End: diff --git a/PPI/Joins.hh b/PPI/Joins.hh index 8960551..a11ac41 100644 --- a/PPI/Joins.hh +++ b/PPI/Joins.hh @@ -31,6 +31,7 @@ #include "predecl.hh" #include "Connectors.hh" #include "Module.hh" +#include "DynamicConnectorMixin.hh" //#include "Joins.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -38,17 +39,6 @@ namespace senf { namespace ppi { -#ifndef DOXYGEN - - template - connector::GenericPassiveInput & connect(Source & source, module::PassiveJoin & target); - - template - connector::GenericActiveInput & connect(Source & source, module::PriorityJoin & target, - int priority = -1); - -#endif - namespace module { /** \brief Join multiple packet streams with passive inputs @@ -71,7 +61,8 @@ namespace module { \ingroup routing_modules */ class PassiveJoin - : public Module + : public Module, + public DynamicConnectorMixin > { SENF_PPI_MODULE(PassiveJoin); public: @@ -80,22 +71,12 @@ namespace module { PassiveJoin(); private: - connector::PassiveInput<> & newInput(); - -#ifndef DOXYGEN - // I didn't get template friend functions to work ... - public: -#endif - template - connector::GenericPassiveInput & connect(Source & source); - - private: + void connectorSetup(connector::PassiveInput<> & conn); void request(connector::GenericPassiveInput & input); void onThrottle(); void onUnthrottle(); - typedef boost::ptr_vector > Inputs; - Inputs inputs_; + friend class DynamicConnectorMixin >; }; /** \brief Join multiple packet streams with active inputs @@ -125,7 +106,8 @@ namespace module { \ingroup routing_modules */ class PriorityJoin - : public Module + : public Module, + public DynamicConnectorMixin > { SENF_PPI_MODULE(PriorityJoin); public: @@ -134,21 +116,12 @@ namespace module { PriorityJoin(); private: - connector::ActiveInput<> & newInput(int priority); - -#ifndef DOXYGEN - public: -#endif - template - connector::GenericActiveInput & connect(Source & source, int prioricty); - - private: + void connectorSetup(PriorityJoin::DynamicConnector & conn, int priority=-1); void request(); void onThrottle(); void onUnthrottle(); - typedef boost::ptr_vector > Inputs; - Inputs inputs_; + friend class DynamicConnectorMixin >; }; }}} @@ -156,7 +129,7 @@ namespace module { ///////////////////////////////hh.e//////////////////////////////////////// #include "Joins.cci" //#include "Joins.ct" -#include "Joins.cti" +//#include "Joins.cti" #endif diff --git a/PPI/Setup.cti b/PPI/Setup.cti index 509bbb1..ca6e672 100644 --- a/PPI/Setup.cti +++ b/PPI/Setup.cti @@ -38,7 +38,7 @@ prefix_ void senf::ppi:: connect(T & source, C & target, typename boost::disable_if< boost::is_base_of >::type *, typename boost::enable_if< boost::is_base_of >::type *, - typename boost::disable_if< boost::is_base_of >::type *) + typename boost::disable_if< boost::is_base_of >::type *) { connect(source.output, target); } @@ -48,7 +48,7 @@ prefix_ void senf::ppi:: connect(C & source, T & target, typename boost::enable_if< boost::is_base_of >::type *, typename boost::disable_if< boost::is_base_of >::type *, - typename boost::disable_if< boost::is_base_of >::type *) + typename boost::disable_if< boost::is_base_of >::type *) { connect(source, target.input); } @@ -58,8 +58,8 @@ prefix_ void senf::ppi:: connect(T1 & source, T2 & target, typename boost::disable_if< boost::is_base_of >::type *, typename boost::disable_if< boost::is_base_of >::type *, - typename boost::disable_if< boost::is_base_of >::type *, - typename boost::disable_if< boost::is_base_of >::type *) + typename boost::disable_if< boost::is_base_of >:: type *, + typename boost::disable_if< boost::is_base_of >:: type *) { connect(source.output, target.input); } diff --git a/PPI/Setup.hh b/PPI/Setup.hh index 7ca5068..7b2c07a 100644 --- a/PPI/Setup.hh +++ b/PPI/Setup.hh @@ -37,6 +37,12 @@ namespace senf { namespace ppi { +namespace detail { + struct DisableStandardInput {}; + struct DisableStandardOutput {}; + struct DisableStandardConnect : public DisableStandardInput, public DisableStandardOutput {}; +} + #ifdef DOXYGEN /** \brief Connect modules @@ -77,20 +83,20 @@ namespace ppi { void connect(T & source, C & target, typename boost::disable_if< boost::is_base_of >::type * = 0, typename boost::enable_if< boost::is_base_of >::type * = 0, - typename boost::disable_if< boost::is_base_of >:: type * = 0); + typename boost::disable_if< boost::is_base_of >::type * = 0); template void connect(C & source, T & target, typename boost::enable_if< boost::is_base_of >::type * = 0, typename boost::disable_if< boost::is_base_of >::type * = 0, - typename boost::disable_if< boost::is_base_of >:: type * = 0); + typename boost::disable_if< boost::is_base_of >::type * = 0); template void connect(T1 & source, T2 & target, typename boost::disable_if< boost::is_base_of >::type * = 0, typename boost::disable_if< boost::is_base_of >::type * = 0, - typename boost::disable_if< boost::is_base_of >:: type * = 0, - typename boost::disable_if< boost::is_base_of >:: type * = 0); + typename boost::disable_if< boost::is_base_of >:: type * = 0, + typename boost::disable_if< boost::is_base_of >:: type * = 0); #endif diff --git a/PPI/predecl.hh b/PPI/predecl.hh index e5b1091..0296cfd 100644 --- a/PPI/predecl.hh +++ b/PPI/predecl.hh @@ -61,6 +61,7 @@ namespace ppi { class BackwardForwardingRouteFromEventImplementation; template class RouteImplementation; + struct DisableStandardConnect; } #endif