![]() |
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_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
1.5.5