Sirikata
|
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_