X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPPI%2FMultiConnectorMixin.hh;h=135c517cf7088ffb5c8ce3da99386cbd483ac174;hb=HEAD;hp=f0d310251bd3880a8d7b539d050049fe7d0dbc4b;hpb=0584aff454ea331f482f830c3ee16d4fdafb3ffb;p=senf.git diff --git a/senf/PPI/MultiConnectorMixin.hh b/senf/PPI/MultiConnectorMixin.hh index f0d3102..135c517 100644 --- a/senf/PPI/MultiConnectorMixin.hh +++ b/senf/PPI/MultiConnectorMixin.hh @@ -1,24 +1,29 @@ // $Id$ // -// Copyright (C) 2009 +// 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. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// 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. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// 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. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Stefan Bund /** \file \brief MultiConnectorMixin public header */ @@ -31,8 +36,6 @@ #include #include #include -#include "Connectors.hh" -#include "Setup.hh" #ifndef SENF_MULTI_CONNECTOR_MAX_ARGS #define SENF_MULTI_CONNECTOR_MAX_ARGS 3 @@ -40,11 +43,11 @@ #include "MultiConnectorMixin.mpp" #include "MultiConnectorMixin.ih" -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { namespace ppi { - + #ifdef DOXYGEN // For exposition only. @@ -61,8 +64,8 @@ namespace ppi { */ template MultiConnectorSource::ConnectorType & connect( - MultiConnectorSource & source, Target & target, A1 const & a1); - + MultiConnectorSource & source, A1 const & a1, Target & target); + /** \brief Connect arbitrary source to MultiConnector target Additional implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments. @@ -92,15 +95,15 @@ namespace ppi { namespace module { - namespace detail { class MultiConnectorMixinAccess; } + namespace detail { struct MultiConnectorMixinAccess; } - /** \brief Multi connector management + /** \brief Multi-Connector management This mixin provides a module with support for a runtime configurable number of input or output connectors. \code - class MyModule - : public senf::ppi::module::Modulem, + class MyModule + : public senf::ppi::module::Module, public senf::ppi::module::MultiConnectorMixin< MyModule, senf::ppi::connector::ActiveInput<> > { @@ -117,13 +120,19 @@ namespace module { 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<> > + MyModule, senf::ppi::connector::ActiveInput<> >; } \endcode @@ -131,6 +140,7 @@ namespace module { \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_ @@ -148,10 +158,8 @@ namespace module { \code container().insert(begin(), container().pop_back().release()); \endcode - which will move the new connector from the end to the beginning. - \warning If you throw an exception from \c connectorSetup(), you must do so \e before moving - the new connector around since the mixin will remove the last element from the container - on an exception. + 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. \par "Example:" senf::ppi::module::PriorityJoin @@ -163,7 +171,7 @@ namespace module { 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 + 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. @@ -175,7 +183,7 @@ namespace module { allocate a new connector \code MyModule muModule; - + senf::ppi::connect(someModule, myModule); \endcode Some modules will expect additional arguments to be passed (see below) @@ -197,16 +205,19 @@ namespace module { \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' + this is known as 'The forwarding problem'). \section senf_ppi_multiconnector_advanced 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::auto_ptr as argument. \c connectorSetup() must ensure to - save this connector in some container or throw an exception + 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 \code - class MyModule + class MyModule : public senf::ppi::module::Module, public senf::ppi::module::MultiConnectorMixin< MyModule, senf::ppi::connector::ActiveInput<>, void, void > @@ -224,6 +235,15 @@ namespace module { connectors_.insert(connectors_.begin()+p,conn); } + void connectorDestroy(ConnectorType const * conn) + { + using boost::lambda::_1; + boost::ptr_vector::iterator i ( + std::find_if(connectors_.begin(),connectors_.end(), &_1==conn)) + if (i != connectors_.end()) + connectors_.erase(i); + } + boost::ptr_vector connectors_; }; \endcode @@ -232,12 +252,12 @@ namespace module { successfully, otherwise your code will break. */ - template ::type> - class MultiConnectorMixin + class MultiConnectorMixin : private detail::MultiConnectorSelectBase::type { public: @@ -245,18 +265,14 @@ namespace module { protected: typedef ContainerType_ ContainerType; ///< Type of connector container + ContainerType_ & connectors(); ///< Get connector container ContainerType_ const & connectors() const; ///< Get connectors container (const) - private: -#if 0 - // For exposition only - // Other implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments accordingly + void connectorDestroy(ConnectorType const &); - tempalte - ConnectorType_ & newConnector(A1 const & a1); + private: -#endif #ifndef DOXYGEN // Include 'MultiConnectorMixin member declaration' from MultiConnectorMixin.mpp @@ -267,17 +283,13 @@ namespace module { 1 )) # include BOOST_PP_ITERATE() -# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ - 0, \ - 2*SENF_MULTI_CONNECTOR_MAX_ARGS, \ - SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ - 9 )) -# include BOOST_PP_ITERATE() - #endif - friend class detail::MultiConnectorMixinAccess; - + void disconnected(ConnectorType_ const & c); + + friend struct detail::MultiConnectorMixinAccess; + friend class detail::MultiConnectorWrapper; + ContainerType_ connectors_; }; @@ -291,33 +303,16 @@ namespace module { { public: typedef ConnectorType_ ConnectorType; - + protected: typedef ContainerType_ ContainerType; + ContainerType_ & connectors(); + ContainerType_ const & connectors() const; - private: + void connectorDestroy(ConnectorType const &); -#if 0 - // For exposition only - // Other implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments accordingly - - tempalte - ConnectorType_ & newConnector(A1 const & a1); - - // See above for an additional note regarding the boost::enable_if in the real - // implementation - - template - friend Source::ConnectorType & senf::ppi::connect(Source & source, - Target & target, - A1 const & a1); - - template - friend Target::ConnectorType & senf::ppi::connect(Source & source, - Target & target, - A1 const & a1); -#endif + private: // Include 'MultiConnectorMixin member declaration' from MultiConnectorMixin.mpp # define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ @@ -326,20 +321,16 @@ namespace module { SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ 1 )) # include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ - 0, \ - 2*SENF_MULTI_CONNECTOR_MAX_ARGS, \ - SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ - 9 )) -# include BOOST_PP_ITERATE() - friend class detail::MultiConnectorMixinAccess; + void disconnected(ConnectorType_ const & c); + + friend struct detail::MultiConnectorMixinAccess; + friend class detail::MultiConnectorWrapper; ContainerType_ connectors_; }; - template class MultiConnectorMixin : private detail::MultiConnectorSelectBase::type @@ -349,27 +340,6 @@ namespace module { private: -#if 0 - // For exposition only - // Other implementations with 0..SENF_MULTI_CONNECTOR_MAX_ARGS arguments accordingly - - tempalte - ConnectorType_ & newConnector(A1 const & a1); - - // See above for an additional note regarding the boost::enable_if in the real - // implementation - - template - friend Source::ConnectorType & senf::ppi::connect(Source & source, - Target & target, - A1 const & a1); - - template - friend Target::ConnectorType & senf::ppi::connect(Source & source, - Target & target, - A1 const & a1); -#endif - // Include 'MultiConnectorMixin member declaration' from MultiConnectorMixin.mpp # define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ 0, \ @@ -378,23 +348,19 @@ namespace module { 1 )) # include BOOST_PP_ITERATE() -# define BOOST_PP_ITERATION_PARAMS_1 (4, ( \ - 0, \ - 2*SENF_MULTI_CONNECTOR_MAX_ARGS, \ - SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ - 9 )) -# include BOOST_PP_ITERATE() + void disconnected(ConnectorType_ const & c); - friend class detail::MultiConnectorMixinAccess; + friend struct detail::MultiConnectorMixinAccess; + friend class detail::MultiConnectorWrapper; }; #endif - + }}} -///////////////////////////////hh.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// //#include "MultiConnectorMixin.cci" -//#include "MultiConnectorMixin.ct" +#include "MultiConnectorMixin.ct" #include "MultiConnectorMixin.cti" #endif