![]() |
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. 16, 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 #include <WNS/events/scheduler/Map.hpp> 00029 00030 using namespace wns::events::scheduler; 00031 00032 STATIC_FACTORY_REGISTER( 00033 Map, 00034 Interface, 00035 "wns.events.scheduler.Map"); 00036 00037 00038 Map::Map() : 00039 Interface(), 00040 Subject<INotification>(), 00041 simTime_(0.0), 00042 events_(), 00043 nowItr_(), 00044 stop_(false), 00045 commandQueue_() 00046 { 00047 events_[0] = new DiscreteTimeContainer(); 00048 nowItr_ = events_.begin(); 00049 } 00050 00051 Map::~Map() 00052 { 00053 while (!events_.empty()) 00054 { 00055 delete events_.begin()->second; 00056 events_.erase(events_.begin()); 00057 } 00058 } 00059 00060 wns::events::scheduler::IEventPtr 00061 Map::doScheduleNow(const Callable& callable) 00062 { 00063 EventPtr event (new wns::events::scheduler::Map::Event(callable)); 00064 event->scheduler_ = this; 00065 event->issued_ = getTime(); 00066 event->scheduled_ = getTime(); 00067 nowItr_->second->push_back(event); 00068 event->state_ = Event::Queued; 00069 return event; 00070 } 00071 00072 wns::events::scheduler::IEventPtr 00073 Map::doSchedule(const Callable& callable, wns::simulator::Time at) 00074 { 00075 EventPtr event (new wns::events::scheduler::Map::Event(callable)); 00076 event->scheduler_ = this; 00077 event->issued_ = getTime(); 00078 event->scheduled_ = at; 00079 EventContainer::iterator itr = events_.find(event->getScheduled()); 00080 if (itr == events_.end()) 00081 { 00082 DiscreteTimeContainer* dtc = new DiscreteTimeContainer(); 00083 // we need to add a new list 00084 dtc->push_back(event); 00085 events_[at] = dtc; 00086 } 00087 else 00088 { 00089 itr->second->push_back(event); 00090 } 00091 event->state_ = Event::Queued; 00092 return event; 00093 } 00094 00095 void 00096 Map::doCancelMapEventCalledFromMapEvent(const EventPtr& event) 00097 { 00098 // we need to notify all obsevers. this is normally done in the Interface, 00099 // but this is called directly from the event ... 00100 sendNotifies(&INotification::onCancelEvent); 00101 doCancelMapEvent(event); 00102 } 00103 00104 void 00105 Map::doCancelMapEvent(const EventPtr& event) 00106 { 00107 if (event->isRunning()) 00108 { 00109 throw IEvent::CancelException("Event is currently being executed"); 00110 } 00111 else if (event->isCanceled()) 00112 { 00113 throw IEvent::CancelException("Event is already canceled"); 00114 } 00115 else if (event->isFinished()) 00116 { 00117 throw IEvent::CancelException("Event has already been called"); 00118 } 00119 else if (event->isNotSubmitted()) 00120 { 00121 throw IEvent::CancelException("Should never happen"); 00122 } 00123 00124 // this removes the element from the list in the scheduler 00125 event->removeFromAllLists(); 00126 event->state_ = Event::Canceled; 00127 } 00128 00129 void 00130 Map::doCancelEvent(const IEventPtr& event) 00131 { 00132 EventPtr mapEvent (dynamicCast<Event>(event)); 00133 assureNotNull(mapEvent); 00134 doCancelMapEvent(mapEvent); 00135 } 00136 00137 bool 00138 Map::doProcessOneEvent() 00139 { 00140 commandQueue_.runCommands(); 00141 00142 // search next event 00143 while (nowItr_->second->empty()) 00144 { 00145 if (events_.size() == 1) 00146 { 00147 // No more events left! 00148 return false; 00149 } 00150 else 00151 { 00152 delete events_.begin()->second; 00153 events_.erase(events_.begin()); 00154 } 00155 nowItr_ = events_.begin(); 00156 } 00157 00158 assure(!nowItr_->second->empty(), "There MUST be events!"); 00159 00160 // get next event 00161 EventPtr nextEvent = nowItr_->second->front(); 00162 00163 wns::simulator::Time newTime = nextEvent->getScheduled(); 00164 00165 // run until all now events are processed 00166 if (simTime_ < newTime) 00167 { 00168 if(stop_) 00169 { 00170 return false; 00171 } 00172 onNewSimTime(newTime); 00173 } 00174 00175 simTime_ = newTime; 00176 00177 nextEvent->state_ = Event::Running; 00178 (*nextEvent)(); 00179 nextEvent->state_ = Event::Finished; 00180 00181 // remove the event 00182 nowItr_->second->pop_front(); 00183 00184 return true; 00185 } 00186 00187 void 00188 Map::doReset() 00189 { 00190 while (!events_.empty()) 00191 { 00192 delete events_.begin()->second; 00193 events_.erase(events_.begin()); 00194 } 00195 events_[0] = new DiscreteTimeContainer(); 00196 nowItr_ = events_.begin(); 00197 simTime_ = 0.0; 00198 commandQueue_.reset(); 00199 } 00200 00201 size_t 00202 Map::doSize() const 00203 { 00204 size_t size = 0; 00205 00206 EventContainer::const_iterator itrEnd = events_.end(); 00207 for (EventContainer::const_iterator itr = events_.begin(); 00208 itr != itrEnd; 00209 ++itr) 00210 { 00211 size += itr->second->size(); 00212 } 00213 return size; 00214 } 00215 00216 void 00217 Map::sendProcessOneEventNotification() 00218 { 00219 sendNotifies(&INotification::onProcessOneEvent); 00220 } 00221 00222 void 00223 Map::sendCancelEventNotification() 00224 { 00225 sendNotifies(&INotification::onCancelEvent); 00226 } 00227 00228 void 00229 Map::sendScheduleNotification() 00230 { 00231 sendNotifies(&INotification::onSchedule); 00232 } 00233 00234 void 00235 Map::sendScheduleNowNotification() 00236 { 00237 sendNotifies(&INotification::onScheduleNow); 00238 } 00239 00240 void 00241 Map::sendScheduleDelayNotification() 00242 { 00243 sendNotifies(&INotification::onScheduleDelay); 00244 } 00245 00246 void 00247 Map::sendAddEventNotification() 00248 { 00249 sendNotifies(&INotification::onAddEvent); 00250 } 00251 00252 wns::simulator::Time 00253 Map::doGetTime() const 00254 { 00255 return simTime_; 00256 } 00257 00258 void 00259 Map::doStart() 00260 { 00261 while(processOneEvent()); 00262 } 00263 00264 void 00265 Map::doStop() 00266 { 00267 stop_ = true; 00268 } 00269 00270 wns::events::scheduler::ICommandPtr 00271 Map::doQueueCommand(const Callable& callable) 00272 { 00273 return commandQueue_.queueCommand(callable); 00274 } 00275 00276 void 00277 Map::doDequeueCommand(const ICommandPtr& command) 00278 { 00279 return commandQueue_.dequeueCommand(command); 00280 }
1.5.5