User Manual, Developers Guide and API Documentation

FlowSeparator.hpp

Go to the documentation of this file.
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 

Generated on Thu May 24 03:31:40 2012 for openWNS by  doxygen 1.5.5