Sirikata
liboh/include/sirikata/oh/RouterElement.hpp
Go to the documentation of this file.
00001 /*  Sirikata
00002  *  RouterElement.hpp
00003  *
00004  *  Copyright (c) 2009, Ewen Cheslack-Postava
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_ROUTER_ELEMENT_
00034 #define _SIRIKATA_ROUTER_ELEMENT_
00035 
00036 #include <sirikata/core/util/Platform.hpp>
00037 #include <sirikata/core/network/IOStrand.hpp>
00038 
00039 namespace Sirikata {
00040 
00041 // Forward declarations of classes below since they need to refer to
00042 // each other
00043 template<typename PacketType>
00044 class DownstreamElementBase;
00045 template<typename PacketType>
00046 class UpstreamElementBase;
00047 
00048 
00052 template<typename PacketType>
00053 class DownstreamElementBase {
00054 public:
00055     typedef UpstreamElementBase<PacketType> InputElement;
00056 
00057     virtual ~DownstreamElementBase() {}
00058 
00066     virtual bool connectInput(uint32 inport, InputElement* elmt, uint32 outport) {
00067         InputPort& i = input(inport);
00068         i.set(elmt, outport);
00069         return true;
00070     }
00071 
00076     virtual bool push(uint32 port, PacketType* pkt) = 0;
00077 
00078 protected:
00082     class InputPort {
00083     public:
00084         InputPort()
00085          : element(NULL),
00086            port()
00087         {}
00088 
00089         bool set(InputElement* elmt, uint32 _port) {
00090             element = elmt;
00091             port = _port;
00092             return true;
00093         }
00094 
00095         PacketType* pull() {
00096             assert(element != NULL);
00097             return element->pull(port);
00098         }
00099 
00100         InputElement* element;
00101         uint32 port;
00102     };
00103 
00104     virtual InputPort& input(uint32 k) = 0;
00105 }; // class DownstreamElementBase
00106 
00108 template<typename PacketType, uint32 NumInputs>
00109 class DownstreamElementFixed : public DownstreamElementBase<PacketType> {
00110 public:
00111     typedef typename DownstreamElementBase<PacketType>::InputElement InputElement;
00112 
00113     DownstreamElementFixed() {
00114         memset(mInputPorts, 0, sizeof(InputPort)*NumInputs);
00115     };
00116 
00117 protected:
00118     typedef typename DownstreamElementBase<PacketType>::InputPort InputPort;
00119 
00120     virtual InputPort& input(uint32 k) {
00121         assert(k < NumInputs);
00122         return mInputPorts[k];
00123     }
00124 
00125     InputPort mInputPorts[NumInputs];
00126 }; // class DownstreamElementFixed
00127 
00129 template<typename PacketType>
00130 class DownstreamElement : public DownstreamElementBase<PacketType> {
00131 public:
00132     typedef typename DownstreamElementBase<PacketType>::InputElement InputElement;
00133 
00134     DownstreamElement(uint32 nports) {
00135         mInputPorts.resize(nports);
00136         for(uint32 i = 0;i < nports; i++)
00137             mInputPorts[i].element = NULL;
00138     };
00139 
00140 protected:
00141     typedef typename DownstreamElementBase<PacketType>::InputPort InputPort;
00142 
00143     virtual InputPort& input(uint32 k) {
00144         assert(k < mInputPorts.size());
00145         return mInputPorts[k];
00146     }
00147 
00148     std::vector<InputPort> mInputPorts;
00149 }; // class DownstreamElement
00150 
00151 
00155 template<typename PacketType>
00156 class UpstreamElementBase {
00157 public:
00158     typedef DownstreamElementBase<PacketType> OutputElement;
00159 
00160     virtual ~UpstreamElementBase() {}
00161 
00169     virtual bool connect(uint32 outport, OutputElement* elmt, uint32 inport) {
00170         OutputPort& o = output(outport);
00171         o.set(elmt, inport);
00172         elmt->connectInput(inport, this, outport);
00173         return true;
00174     }
00175 
00180     virtual PacketType* pull(uint32 port) = 0;
00181 
00182 protected:
00186     class OutputPort {
00187     public:
00188         OutputPort()
00189          : element(NULL),
00190            port()
00191         {}
00192 
00193         bool set(OutputElement* elmt, uint32 _port) {
00194             element = elmt;
00195             port = _port;
00196             return true;
00197         }
00198 
00199         bool push(PacketType* pkt) {
00200             assert(element != NULL);
00201             return element->push(port, pkt);
00202         }
00203 
00204         OutputElement* element;
00205         uint32 port;
00206     };
00207 
00208     virtual OutputPort& output(uint32 k) = 0;
00209 }; // class UpstreamElementBase
00210 
00212 template<typename PacketType, uint32 NumOutputs>
00213 class UpstreamElementFixed : public UpstreamElementBase<PacketType> {
00214 public:
00215     typedef typename UpstreamElementBase<PacketType>::OutputElement OutputElement;
00216 
00217     UpstreamElementFixed() {
00218         memset(mOutputPorts, 0, sizeof(OutputPort)*NumOutputs);
00219     };
00220 
00221 protected:
00222     typedef typename UpstreamElementBase<PacketType>::OutputPort OutputPort;
00223 
00224     virtual OutputPort& output(uint32 k) {
00225         assert(k < NumOutputs);
00226         return mOutputPorts[k];
00227     }
00228 
00229     OutputPort mOutputPorts[NumOutputs];
00230 }; // class UpstreamElementFixed
00231 
00233 template<typename PacketType>
00234 class UpstreamElement : public UpstreamElementBase<PacketType> {
00235 public:
00236     typedef typename UpstreamElementBase<PacketType>::OutputElement OutputElement;
00237 
00238     UpstreamElement(uint32 nports) {
00239         mOutputPorts.resize(nports);
00240         for(uint32 i = 0;i < nports; i++)
00241             mOutputPorts[i].element = NULL;
00242     };
00243 
00244 protected:
00245     typedef typename UpstreamElementBase<PacketType>::OutputPort OutputPort;
00246 
00247     virtual OutputPort& input(uint32 k) {
00248         assert(k < mOutputPorts.size());
00249         return mOutputPorts[k];
00250     }
00251 
00252     std::vector<OutputPort> mOutputPorts;
00253 }; // class UpstreamElement
00254 
00255 
00257 template<typename PacketType>
00258 class RouterElement : public DownstreamElement<PacketType>, public UpstreamElement<PacketType> {
00259 public:
00260     typedef typename UpstreamElement<PacketType>::OutputElement OutputElement;
00261     typedef typename DownstreamElement<PacketType>::InputElement InputElement;
00262 protected:
00263     typedef typename UpstreamElement<PacketType>::InputPort InputPort;
00264     typedef typename DownstreamElement<PacketType>::OutputPort OutputPort;
00265 }; // class RouterElement
00266 
00267 
00268 } // namespace Sirikata
00269 
00270 #endif //_SIRIKATA_ROUTER_ELEMENT_