User Manual, Developers Guide and API Documentation

ShortcutFU.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_SHORTCUTFU_HPP
00029 #define WNS_LDK_SHORTCUTFU_HPP
00030 
00031 #include <WNS/ldk/FunctionalUnit.hpp>
00032 #include <WNS/distribution/Distribution.hpp>
00033 
00034 #include <boost/bind.hpp>
00035 
00036 #include <deque>
00037 
00038 
00039 namespace wns { namespace ldk {
00046         template<typename ADDRESS, typename ELEMENT>
00047         //class ShortcutFU : public fu::Plain<ShortcutFU<ADDRESS, ELEMENT> >
00048         class ShortcutFU : public FunctionalUnit
00049         {
00050         public:
00051             ShortcutFU(fun::FUN* _fun, const wns::pyconfig::View& _pyco) :
00052                 scheduler(wns::simulator::getEventScheduler()),
00053                 logger(_pyco.getView("logger"))
00054             {
00055                 wns::pyconfig::View distConfig = _pyco.getView("delay");
00056                 std::string pluginName = distConfig.get<std::string>("__plugin__");
00057                 wns::distribution::DistributionCreator* dc = 
00058                     wns::distribution::DistributionFactory::creator(pluginName);
00059 
00060                 delay = dc->create(_pyco.get("delay"));
00061                 offset = _pyco.get<simTimeType>("offset");
00062 
00063                 scheduler->scheduleDelay(boost::bind(&ShortcutFU<ADDRESS, ELEMENT>::sendCompoundsInQueue, (ELEMENT)this), offset);
00064             }
00065 
00066             virtual
00067             ~ShortcutFU()
00068             {
00069                 ContainerType& myReg = getElementRegistry();
00070                 for(typename ContainerType::const_iterator it=myReg.begin(); it!=myReg.end(); ++it)
00071                 {
00072                     if (it->second == this)
00073                     {
00074                         myReg.erase(it->first);
00075                     }
00076                 }
00077             }
00078 
00079             virtual bool
00080             doIsAccepting(const wns::ldk::CompoundPtr&) const { return true; }
00081 
00082             virtual void
00083             doWakeup() {assure(false, "Configuration error: No FU below allowed!");}
00084 
00085             // CompoundHandlerInterface
00086             virtual void
00087             doSendData(const wns::ldk::CompoundPtr& _compound)
00088             {
00089                 assure(_compound, "doSendData called with invalid compound!");
00090 
00091                 compoundQueue.push_back(_compound);
00092             }
00093 
00094             virtual void
00095             doOnData(const wns::ldk::CompoundPtr& _compound)
00096             {
00097                 assure(_compound, "doOnData called with invalid compound!");
00098 
00099                 MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00100                 m << ": doOnData(), forwading to higher FU";
00101                 MESSAGE_END();
00102 
00103                 getDeliverer()->getAcceptor(_compound)->onData(_compound);
00104             }
00105 
00109             virtual bool
00110             isReceiver() = 0;
00111 
00115             virtual ADDRESS
00116             getSourceAddress() = 0;
00117 
00121             virtual ADDRESS
00122             getDestinationAddress(const wns::ldk::CompoundPtr&) = 0;
00123 
00127             virtual bool
00128             isBroadcast(const wns::ldk::CompoundPtr&) = 0;
00129 
00130             virtual void
00131             onFUNCreated()
00132             {
00133                 ContainerType& myReg = getElementRegistry();
00134                 if (isReceiver())
00135                 {
00136                     myReg.insert(getSourceAddress(), (ELEMENT)this);
00137                     MESSAGE_SINGLE(NORMAL, logger, "ShortcutFU "  << this->getFUN()->getName() << " registered with" << " address " << getSourceAddress());
00138                 }
00139             }
00140 
00141             void
00142             sendCompoundsInQueue()
00143             {
00144                 while (not compoundQueue.empty())
00145                 {
00146                     const wns::ldk::CompoundPtr compound = compoundQueue.front();
00147                     compoundQueue.erase(compoundQueue.begin());
00148 
00149                     if (isBroadcast(compound))
00150                     {
00151                         typename ContainerType::const_iterator it;
00152                         for(it = getElementRegistry().begin();
00153                             it != getElementRegistry().end();
00154                            ++it)
00155                         {
00156                             it->second->doOnData(compound);
00157                         }
00158                         continue;
00159                     }
00160 
00161                     ADDRESS destAddr = getDestinationAddress(compound);
00162                     ELEMENT peerFU = getElementRegistry().find(destAddr);
00163 
00164                     peerFU->doOnData(compound);
00165                 }
00166 
00167                 scheduler->scheduleDelay(boost::bind(&ShortcutFU<ADDRESS, ELEMENT>::sendCompoundsInQueue, (ELEMENT)this), (*delay)());
00168             }
00169 
00170             void
00171             reset()
00172             {
00173                 getElementRegistry().clear();
00174                 compoundQueue.clear();
00175             }
00176 
00177             typedef wns::container::Registry<ADDRESS, ELEMENT, wns::container::registry::NoneOnErase> ContainerType;
00178 
00179         private:
00180             wns::events::scheduler::Interface* scheduler;
00181 
00185             wns::distribution::Distribution* delay;
00186 
00190             simTimeType offset;
00191 
00195             std::deque<wns::ldk::CompoundPtr> compoundQueue;
00196 
00197         protected:
00198             wns::logger::Logger logger;
00199 
00200             ContainerType&
00201             getElementRegistry() { static ContainerType reg; return reg;}
00202         };
00203     }
00204 }
00205 
00206 #endif // WNS_LDK_SHORTCUTFU_HPP

Generated on Fri May 25 03:31:47 2012 for openWNS by  doxygen 1.5.5