Packets: not really a smart but efficient 'shortcut' for ConcretePacket::next() ...
[senf.git] / senf / PPI / Joins.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Joins public header */
30
31 #ifndef HH_SENF_PPI_Joins_
32 #define HH_SENF_PPI_Joins_ 1
33
34 // Custom includes
35 #include "Connectors.hh"
36 #include "Module.hh"
37 #include "MultiConnectorMixin.hh"
38
39 //#include "Joins.mpp"
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 namespace senf {
43 namespace ppi {
44
45 namespace module {
46
47     /** \brief Join multiple packet streams with passive inputs
48
49         The PassiveJoin will combine any number of packet streams. You may connect any number of
50         ActiveOutput<>'s  to the PassiveJoin instance. The combined stream is then provided on the
51         ActiveOutput<> \a output.
52
53         Since PassiveJoin allows any number of incoming packet streams, the input connectors are
54         dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
55         the needed input connectors. This hides this extra functionality from the user.
56         \code
57         senf::ppi::module::PassiveJoin join;
58
59         ppi::connect(module1,join);             // Connect first module to join's input
60         ppi::connect(module2.some_output,join); // Connect another module to join's input
61         ppi::connect(join,module3);             // Forward combined stream to module3
62         \endcode
63
64         \ingroup routing_modules
65      */
66     class PassiveJoin
67         : public Module,
68           public MultiConnectorMixin<PassiveJoin, connector::PassiveInput<> >
69     {
70         SENF_PPI_MODULE(PassiveJoin);
71     public:
72         connector::ActiveOutput<> output;
73
74         PassiveJoin();
75
76     private:
77         void connectorSetup(connector::PassiveInput<> & conn);
78         void request(connector::GenericPassiveInput & input);
79         void onThrottle();
80         void onUnthrottle();
81
82         friend class MultiConnectorMixin<PassiveJoin, connector::PassiveInput<> >;
83     };
84
85     /** \brief Join multiple packet streams with active inputs
86
87         The PriorityJoin will combine any number of packet streams. You may connect any number of
88         PassiveInput<>'s  to the PassiveJoin instance. The combined stream is then provided on the
89         PassiveOutput<> \a output.
90
91         When a packet request is received on Priorityjoin's \a output, The request will be serviced
92         from the first unthrottled input. The order, in which connectors are connected to the
93         PriorityJoin's input is important: The earlier connected peer has the higher priority and
94         will be serviced first.
95
96         Since PriorityJoin allows any number of incoming packet streams, the input connectors are
97         dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
98         the needed input connectors. This hides this extra functionality from the user.
99         \code
100         senf::ppi::module::PriorityJoin join;
101
102         ppi::connect(module1,join);             // Connect first module to join's input
103         ppi::connect(module2.some_output,join); // Connect another module to join's input
104         ppi::connect(join,module3);             // Forward combined stream to module3
105         \endcode
106         Here, \a module1 has higher priority than \a module2 which will only be queried if \a
107         module1 is throttled.
108
109         \ingroup routing_modules
110      */
111     class PriorityJoin
112         : public Module,
113           public MultiConnectorMixin<PriorityJoin, connector::ActiveInput<> >
114     {
115         SENF_PPI_MODULE(PriorityJoin);
116     public:
117         connector::PassiveOutput<> output;
118
119         PriorityJoin();
120
121     private:
122         void connectorSetup(PriorityJoin::ConnectorType & conn, int priority=-1);
123         void request();
124         void onThrottle();
125         void onUnthrottle();
126
127         friend class MultiConnectorMixin<PriorityJoin, connector::ActiveInput<> >;
128     };
129
130 }}}
131
132 //-/////////////////////////////////////////////////////////////////////////////////////////////////
133 #include "Joins.cci"
134 //#include "Joins.ct"
135 //#include "Joins.cti"
136 #endif
137
138 \f
139 // Local Variables:
140 // mode: c++
141 // fill-column: 100
142 // comment-column: 40
143 // c-file-style: "senf"
144 // indent-tabs-mode: nil
145 // ispell-local-dictionary: "american"
146 // compile-command: "scons -u test"
147 // End: