00001
00002 #ifndef SIMULATOR_H
00003 #define SIMULATOR_H
00004
00186 #include <vector>
00187 #include <set>
00188 using namespace std;
00189 #include <boost/utility.hpp>
00190 #include <boost/smart_ptr.hpp>
00191 #include <boost/enable_shared_from_this.hpp>
00192
00193 #include "utility.hpp"
00194 #include "sim_time.hpp"
00195 #include "event.hpp"
00196 #include "node.hpp"
00197 #include "simulation_end_listener.hpp"
00198
00199 class RandNumGenerator;
00200 typedef boost::shared_ptr<RandNumGenerator> RandNumGeneratorPtr;
00201 class LogStreamManager;
00202 typedef LogStreamManager* LogStreamManagerPtr;
00203
00205
00207
00214 class EventPtrComparator {
00215 public:
00221 inline bool operator() (ConstEventPtr event1,
00222 ConstEventPtr event2) const;
00223 };
00224
00225 inline bool EventPtrComparator::operator() (ConstEventPtr event1,
00226 ConstEventPtr event2) const
00227 {
00228 return *event1 < *event2;
00229 }
00230
00232
00234
00235 typedef multiset<EventPtr,EventPtrComparator> EventPtrQueue;
00236 typedef EventPtrQueue::iterator EventPtrQueueIterator;
00237
00242
00243
00244 class Simulator : boost::noncopyable,
00245 public boost::enable_shared_from_this<Simulator> {
00246 public:
00248 typedef Simulator* SimulatorPtr;
00249
00254 static inline SimulatorPtr instance();
00255
00260 inline void addNode(NodePtr nodeToAdd);
00261
00273 void runSimulation(const SimTime& stopTime);
00274
00279 inline SimTime currentTime() const;
00280
00294 inline bool scheduleEvent(EventPtr eventToSchedule,
00295 const SimTime& eventDelay);
00296
00306 inline bool cancelEvent(EventPtr eventToCancel);
00307
00313 inline void setLogStreamManager(
00314 LogStreamManagerPtr logStreamManager) const;
00315
00320 inline LogStreamManagerPtr getLogStreamManager() const;
00321
00327 void seedRandNumGenerator(const t_uint seed) const;
00328
00333 inline RandNumGeneratorPtr getRandNumGenerator() const;
00334
00340 void reset();
00341
00347 inline void addSimulationEndListener(
00348 SimulationEndListenerPtr listener);
00349
00350 private:
00351
00353 static const double m_SIM_START_TIME;
00354
00357 static SimulatorPtr m_instance;
00358
00361 SimTime m_clock;
00362
00367 EventPtrQueue m_eventPtrQueue;
00368
00372 LogStreamManagerPtr m_logStreamManagerPtr;
00373
00377 RandNumGeneratorPtr m_randNumGeneratorPtr;
00378
00382 vector<SimulationEndListenerPtr> m_simulationEndListeners;
00383
00385 Simulator();
00386
00390 ~Simulator();
00391
00401 inline void dispatchEvent(EventPtr event);
00402
00408 inline EventPtr getNextEvent();
00409
00410 };
00411 typedef Simulator* SimulatorPtr;
00412
00414
00416
00417 inline SimTime Simulator::currentTime() const
00418 {
00419 return m_clock;
00420 }
00421
00422 inline void Simulator::addNode(NodePtr nodeToAdd)
00423 {
00424
00425 }
00426
00427 inline bool Simulator::scheduleEvent(EventPtr eventToSchedule,
00428 const SimTime& eventDelay)
00429 {
00430 assert(eventToSchedule != 0);
00431 assert(!eventToSchedule->inEventQueue());
00432 assert(eventDelay >= 0.0);
00433
00434 eventToSchedule->setFireTime(currentTime() + eventDelay);
00435 EventPtrQueue::const_iterator insertIterator =
00436 m_eventPtrQueue.insert(eventToSchedule);
00437 bool didInsert = (insertIterator != m_eventPtrQueue.end());
00438 if(didInsert) {
00439 eventToSchedule->setInEventQueue(true);
00440 }
00441
00442 return didInsert;
00443
00444 }
00445
00446 inline bool Simulator::cancelEvent(EventPtr eventToCancel)
00447 {
00448 assert(eventToCancel != 0);
00449
00450
00451
00452 pair<EventPtrQueueIterator,EventPtrQueueIterator> keyIteratorPair =
00453 m_eventPtrQueue.equal_range(eventToCancel);
00454
00455 bool didErase = false;
00456
00457 for(EventPtrQueueIterator keyIterator = keyIteratorPair.first;
00458 keyIterator != keyIteratorPair.second;
00459 ++keyIterator) {
00460
00461
00462
00463 if(*keyIterator == eventToCancel) {
00464 m_eventPtrQueue.erase(keyIterator);
00465 eventToCancel->setInEventQueue(false);
00466 didErase = true;
00467 break;
00468 }
00469 }
00470
00471 return didErase;
00472 }
00473
00474 inline RandNumGeneratorPtr Simulator::getRandNumGenerator() const
00475 {
00476 assert(m_randNumGeneratorPtr != 0);
00477 return m_randNumGeneratorPtr;
00478 }
00479
00480 inline LogStreamManagerPtr Simulator::getLogStreamManager() const
00481 {
00482 assert(m_logStreamManagerPtr != 0);
00483 return m_logStreamManagerPtr;
00484 }
00485
00486 inline SimulatorPtr Simulator::instance()
00487 {
00488
00489 if(m_instance == 0) {
00490 m_instance = new Simulator();
00491 }
00492 return m_instance;
00493 }
00494
00495 inline void Simulator::dispatchEvent(EventPtr event)
00496 {
00497 assert(event.get() != 0);
00498 SimTime fireTime = event->getFireTime();
00499 assert(m_clock <= fireTime);
00500
00501 m_clock = fireTime;
00502 event->execute();
00503 }
00504
00505 inline EventPtr Simulator::getNextEvent()
00506 {
00507 EventPtr nextEvent (*m_eventPtrQueue.begin());
00508 m_eventPtrQueue.erase(m_eventPtrQueue.begin());
00509 nextEvent->setInEventQueue(false);
00510 return nextEvent;
00511 }
00512
00513 inline void Simulator::addSimulationEndListener(
00514 SimulationEndListenerPtr listener)
00515 {
00516 m_simulationEndListeners.push_back(listener);
00517 }
00518
00519 #endif // SIMULATOR_H
00520