![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #ifndef WNS_LDK_FLOWSEPARATOR_HPP 00029 #define WNS_LDK_FLOWSEPARATOR_HPP 00030 00031 #include <WNS/ldk/CommandTypeSpecifier.hpp> 00032 #include <WNS/ldk/ControlServiceInterface.hpp> 00033 #include <WNS/ldk/fu/Plain.hpp> 00034 #include <WNS/ldk/fun/FUN.hpp> 00035 #include <WNS/ldk/Key.hpp> 00036 #include <WNS/ldk/flowseparator/NotFoundStrategy.hpp> 00037 #include <WNS/ldk/flowseparator/FlowInfoProvider.hpp> 00038 #include <WNS/ldk/flowseparator/CreatorStrategy.hpp> 00039 00040 #include <WNS/distribution/Uniform.hpp> 00041 00042 #include <WNS/DerefLess.hpp> 00043 #include <WNS/logger/Logger.hpp> 00044 00045 #include <WNS/StaticFactory.hpp> 00046 #include <WNS/pyconfig/View.hpp> 00047 00048 #include <WNS/Enum.hpp> 00049 00050 #include <string> 00051 #include <map> 00052 #include <memory> 00053 00054 namespace wns { namespace ldk { 00055 00061 ENUM_BEGIN(Direction); 00062 ENUM(INCOMING, 0); 00063 ENUM(OUTGOING, 1); 00064 ENUM_END(); 00065 00076 class FlowSeparator : 00077 public FunctionalUnit, 00078 public CommandTypeSpecifier<>, 00079 public HasReceptor<>, 00080 public HasConnector<>, 00081 public HasDeliverer<>, 00082 public NotCloneable 00083 { 00084 class InstanceNotFound : 00085 public Exception 00086 { 00087 public: 00088 explicit 00089 InstanceNotFound(const ConstKeyPtr& _key) : 00090 Exception("Instance to the following key not found:"), 00091 key(_key) 00092 { 00093 (*this) << this->key->str(); 00094 } 00095 00096 virtual 00097 ~InstanceNotFound() throw() 00098 {} 00099 00100 ConstKeyPtr key; 00101 }; 00102 00103 template <class RECEPTACLETYPE> 00104 class ReceptacleManagement 00105 { 00106 public: 00107 typedef std::map<ConstKeyPtr, RECEPTACLETYPE*, DerefLess<ConstKeyPtr> > ReceptacleContainer; 00108 00109 ReceptacleManagement(FlowSeparator* fs) 00110 : fs_(fs), 00111 receptacleContainer_() 00112 {} 00113 00114 ~ReceptacleManagement() 00115 {} 00116 00117 void 00118 addInstance(const ConstKeyPtr& key, RECEPTACLETYPE* receptacle) 00119 { 00120 assure(NULL == getInstance(key), 00121 "trying to add an instance for an already known key."); 00122 00123 MESSAGE_BEGIN(NORMAL, fs_->logger, m, fs_->getFUN()->getName()); 00124 m <<": Add receptacle for Instance/Flow Key: "<< key->str() 00125 << "; FU: " << receptacle->getFU()->getName(); 00126 MESSAGE_END(); 00127 00128 receptacleContainer_[key] = receptacle; 00129 } 00130 00131 void 00132 removeInstance(const ConstKeyPtr& key) 00133 { 00134 typename ReceptacleContainer::iterator it = receptacleContainer_.find(key); 00135 assure(it != receptacleContainer_.end(), 00136 "trying to disintegrate receptacle for an unknown key."); 00137 00138 assure(fs_->instanceBusy != fs_->instances.find(key)->second, 00139 "ReceptacleManagement::removeInstance: Can't remove busy Instance/Flow!"); 00140 00141 receptacleContainer_.erase(it); 00142 } 00143 00144 RECEPTACLETYPE* 00145 getInstance(const ConstKeyPtr& key) const 00146 { 00147 typename ReceptacleContainer::const_iterator it = receptacleContainer_.find(key); 00148 00149 if(it == receptacleContainer_.end()) 00150 { 00151 return NULL; 00152 } 00153 00154 return it->second; 00155 } // getInstance 00156 00157 RECEPTACLETYPE* 00158 _getInstance(const CompoundPtr& compound, int direction) const 00159 { 00160 ConstKeyPtr key = (*(fs_->keyBuilder))(compound, direction); 00161 00162 typename ReceptacleContainer::const_iterator it = receptacleContainer_.find(key); 00163 00164 if(it == receptacleContainer_.end()) 00165 { 00166 throw InstanceNotFound(key); 00167 } 00168 00169 MESSAGE_BEGIN(VERBOSE, fs_->logger, m, fs_->getFUN()->getName()); 00170 m << ": " 00171 << "reusing instance for key " 00172 << key->str(); 00173 MESSAGE_END(); 00174 00175 return it->second; 00176 } // getInstance 00177 00178 RECEPTACLETYPE* 00179 tryGetInstanceAndInsertPermanent(const CompoundPtr& compound, int direction) 00180 { 00181 RECEPTACLETYPE* receptacle = NULL; 00182 try 00183 { 00184 receptacle = _getInstance(compound, direction); 00185 } 00186 catch(const InstanceNotFound& ifn) 00187 { 00188 MESSAGE_SINGLE( 00189 VERBOSE, 00190 fs_->logger, 00191 fs_->getFUN()->getName()<<": " << 00192 "adding new instance for key (" << 00193 ifn.key->str() << 00194 ") permanently to FlowSeparator"); 00195 fs_->addInstance(ifn.key); 00196 00197 // try, if we now get the missing instance 00198 try 00199 { 00200 receptacle = _getInstance(compound, direction); 00201 } 00202 catch(const InstanceNotFound& ifn) 00203 { 00204 wns::Exception e; 00205 e << "Creation of new instance failed"; 00206 throw e; 00207 } 00208 } 00209 // throw on 00210 catch(...) 00211 { 00212 throw; 00213 } 00214 return receptacle; 00215 } 00216 00217 protected: 00218 FlowSeparator* fs_; 00219 ReceptacleContainer receptacleContainer_; 00220 }; 00221 00222 class ConnectorReceptacleSeparator 00223 : public ReceptacleManagement<IConnectorReceptacle>, 00224 public IConnectorReceptacle 00225 { 00226 public: 00227 00228 ConnectorReceptacleSeparator(FlowSeparator* fs, std::string portname); 00229 ~ConnectorReceptacleSeparator(); 00230 00231 virtual void 00232 sendData(const CompoundPtr& compound); 00233 00234 virtual void 00235 doSendData(const CompoundPtr& compound); 00236 00237 virtual bool 00238 isAccepting(const CompoundPtr& compound); 00239 00240 virtual bool 00241 doIsAccepting(const CompoundPtr& compound) const; 00242 00243 virtual FunctionalUnit* 00244 getFU(); 00245 00246 private: 00247 std::string portname_; 00248 00249 }; 00250 00251 class DelivererReceptacleSeparator 00252 : public ReceptacleManagement<IDelivererReceptacle>, 00253 public IDelivererReceptacle 00254 { 00255 public: 00256 DelivererReceptacleSeparator(FlowSeparator* fs); 00257 ~DelivererReceptacleSeparator(); 00258 00259 virtual void 00260 onData(const CompoundPtr& compound); 00261 00262 virtual void 00263 doOnData(const CompoundPtr& compound); 00264 00265 virtual FunctionalUnit* 00266 getFU(); 00267 }; 00268 00269 class ReceptorReceptacleSeparator 00270 : public ReceptacleManagement<IReceptorReceptacle>, 00271 public IReceptorReceptacle 00272 { 00273 public: 00274 ReceptorReceptacleSeparator(FlowSeparator* fs); 00275 ~ReceptorReceptacleSeparator(); 00276 00277 virtual void 00278 wakeup(); 00279 00280 virtual void 00281 doWakeup(); 00282 00283 virtual FunctionalUnit* 00284 getFU(); 00285 }; 00286 00287 public: 00288 typedef std::map<ConstKeyPtr, FunctionalUnit*, DerefLess<ConstKeyPtr> > InstanceMap; 00289 typedef std::list<std::string> StringList; 00290 typedef std::list<ConnectorReceptacleSeparator*> ConnectorReceptacleSeparatorList; 00291 typedef std::list<DelivererReceptacleSeparator*> DelivererReceptacleSeparatorList; 00292 typedef std::list<ReceptorReceptacleSeparator*> ReceptorReceptacleSeparatorList; 00293 00294 friend class ConnectorReceptacleSeparator; 00295 00300 FlowSeparator( 00301 fun::FUN* fuNet, 00302 const pyconfig::View& _config, 00303 std::auto_ptr<KeyBuilder> _keyBuilder, 00304 std::auto_ptr<flowseparator::NotFoundStrategy> _notFound); 00305 00310 FlowSeparator( 00311 fun::FUN* fuNet, 00312 const pyconfig::View& _config); 00313 00314 FlowSeparator(const FlowSeparator&); 00315 00316 00317 virtual 00318 ~FlowSeparator(); 00319 00320 00321 virtual void 00322 onFUNCreated(); 00323 00328 virtual std::size_t 00329 size() const; 00330 00336 FunctionalUnit* 00337 getInstance(const ConstKeyPtr& key) const; 00338 00339 FunctionalUnit* 00340 getInstance(const CompoundPtr& compound, int direction) const; 00344 ConstKeyPtr 00345 getKey(const CompoundPtr& compound, int direction) const; 00346 00353 void 00354 addInstance(const ConstKeyPtr& key, FunctionalUnit* functionalUnit); 00355 00362 void 00363 addInstance(const ConstKeyPtr& key); 00364 00370 void 00371 removeInstance(const ConstKeyPtr& key); 00372 00373 private: 00374 void 00375 init(); 00376 00390 virtual void 00391 doSendData(const CompoundPtr& compound); 00392 00393 virtual void 00394 doOnData(const CompoundPtr& compound); 00395 00396 virtual bool 00397 doIsAccepting(const CompoundPtr& compound) const; 00398 00399 virtual void 00400 doWakeup(); 00402 00409 void 00410 connectFU(FunctionalUnit* functionalUnit) const; 00411 00418 void 00419 integrate(const ConstKeyPtr& key, FunctionalUnit* functionalUnit); 00420 00426 void 00427 disintegrate(const ConstKeyPtr& key); 00428 00429 00430 InstanceMap instances; 00431 ConnectorReceptacleSeparatorList crsList_; 00432 DelivererReceptacleSeparatorList drsList_; 00433 ReceptorReceptacleSeparatorList rrsList_; 00434 00435 FunctionalUnit* prototypeFU_; 00436 ConnectorReceptacleSeparator* connectorReceptacleSinglePort_; 00437 DelivererReceptacleSeparator* delivererReceptacleSinglePort_; 00438 ReceptorReceptacleSeparator* receptorReceptacleSinglePort_; 00439 FunctionalUnit* instanceBusy; 00440 00441 pyconfig::View config; 00442 00443 std::auto_ptr<KeyBuilder> keyBuilder; 00444 00445 std::auto_ptr<flowseparator::NotFoundStrategy> notFound; 00446 00447 wns::distribution::StandardUniform dis; 00448 00449 logger::Logger logger; 00450 }; 00451 00452 } // namespace ldk 00453 } // namespace wns 00454 00455 00456 #endif // NOT defined WNS_LDK_FLOWSEPARATOR_HPP 00457 00458
1.5.5