85c113353df593b221c02d68ec4d61af04f70eef
[senf.git] / PPI / MultiConnectorMixin.hh
1 // $Id$
2 //
3 // Copyright (C) 2009 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief MultiConnectorMixin public header */
25
26 #ifndef HH_SENF_PPI_MultiConnectorMixin_
27 #define HH_SENF_PPI_MultiConnectorMixin_ 1
28
29 // Custom includes
30 #include "../config.hh"
31 #include <boost/ptr_container/ptr_map.hpp>
32 #include <boost/ptr_container/ptr_vector.hpp>
33 #include <boost/mpl/if.hpp>
34 #include "Connectors.hh"
35 #include "Setup.hh"
36
37 #include "MultiConnectorMixin.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
39
40 #ifndef SENF_MULTI_CONNECTOR_MAX_ARGS
41 #define SENF_MULTI_CONNECTOR_MAX_ARGS 3
42 #endif
43
44 namespace senf {
45 namespace ppi {
46
47 #   define BOOST_PP_ITERATION_PARAMS_1 (4, ( \
48             0, \
49             SENF_MULTI_CONNECTOR_MAX_ARGS, \
50             SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
51             2 ))
52 #   include BOOST_PP_ITERATE()
53
54 namespace module {
55
56 namespace detail {
57     template <class KeyType, class ConnectorType>
58     struct DefaultMultiConnectorContainer 
59     { typedef boost::ptr_map<KeyType, ConnectorType> type; };
60
61     template <class ConnectorType>
62     struct DefaultMultiConnectorContainer<void,ConnectorType> 
63     { typedef boost::ptr_vector<ConnectorType> type; };
64
65     template <class ConnectorType>
66     struct DynamicDisableType
67         : public boost::mpl::if_< 
68               boost::is_base_of<connector::InputConnector, ConnectorType>,
69               ppi::detail::DisableStandardInput, ppi::detail::DisableStandardOutput >
70     {};
71 }
72
73     /** \brief Dynamic connector management
74
75         Provide modules with support for dynamic connectors.
76
77         \li A module might have dynamic input or output connectors
78         \li Creating a new connection might take an argument
79         \li Connectors are stored either in a vector or a map
80         
81         Workflow:
82         \li Connectors are created by the helper.
83         \li Connector is passed to Self::connectorSetup. This returns either void or the map
84             key. connectorSetup must setup internal routing and callbacks.
85         \li Connector inserted into container.
86
87         connectorSetup may take additional arguments besides reference to connector. These arguments
88         are taken from the trailing ppi::connect call arguments.
89
90         The list manager will insert the new connector at the end of the list BEFORE calling
91         connetorSetup. This allows the setup routine to manipulate the position.
92      */
93     template <class Self_, 
94               class ConnectorType_, 
95               class KeyType_=void, 
96               class ContainerType_=typename detail::DefaultMultiConnectorContainer<
97                                                KeyType_,ConnectorType_>::type>
98     class MultiConnectorMixin 
99         : private detail::DynamicDisableType<ConnectorType_>::type
100     {
101     public:
102         typedef ConnectorType_ ConnectorType;
103
104     protected:
105         typedef ContainerType_ ContainerType;
106         ContainerType_ & connectors();
107
108     private:
109 #       define BOOST_PP_ITERATION_PARAMS_1 (4, ( \
110             0, \
111             SENF_MULTI_CONNECTOR_MAX_ARGS, \
112             SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
113             1 ))
114 #       include BOOST_PP_ITERATE()
115         
116         ContainerType_ connectors_;
117     };
118
119     template <class Self_,
120               class ConnectorType_,
121               class ContainerType_>
122     class MultiConnectorMixin<Self_,ConnectorType_,void,ContainerType_>
123         : private detail::DynamicDisableType<ConnectorType_>::type
124     {
125     public:
126         typedef ConnectorType_ ConnectorType;
127         
128     protected:
129         typedef ContainerType_ ContainerType;
130         ContainerType_ & connectors();
131
132     private:
133 #       define BOOST_PP_ITERATION_PARAMS_1 (4, ( \
134             0, \
135             SENF_MULTI_CONNECTOR_MAX_ARGS, \
136             SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
137             1 ))
138 #       include BOOST_PP_ITERATE()
139         
140         ContainerType_ connectors_;
141     };
142         
143 }}}
144
145 ///////////////////////////////hh.e////////////////////////////////////////
146 //#include "MultiConnectorMixin.cci"
147 //#include "MultiConnectorMixin.ct"
148 #include "MultiConnectorMixin.cti"
149 #endif
150
151 \f
152 // Local Variables:
153 // mode: c++
154 // fill-column: 100
155 // comment-column: 40
156 // c-file-style: "senf"
157 // indent-tabs-mode: nil
158 // ispell-local-dictionary: "american"
159 // compile-command: "scons -u test"
160 // End: