simulator.hpp

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 // EventPtrComparator Class
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 // Simulator Class
00234 
00235 typedef multiset<EventPtr,EventPtrComparator> EventPtrQueue;
00236 typedef EventPtrQueue::iterator EventPtrQueueIterator;
00237 
00242 // Declare as noncopyable so the copy constructor and copy 
00243 // assignment cannot be used.
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 // Inline Functions
00416 
00417 inline SimTime Simulator::currentTime() const
00418 {
00419    return m_clock;
00420 }
00421 
00422 inline void Simulator::addNode(NodePtr nodeToAdd)
00423 {
00424    // May keep track of the nodes globally in the future.
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    // Get the range of elements that match this key (i.e.,
00451    // have the same fire time).
00452    pair<EventPtrQueueIterator,EventPtrQueueIterator> keyIteratorPair =
00453       m_eventPtrQueue.equal_range(eventToCancel);
00454       
00455    bool didErase = false;
00456    // If the key was not found, pair.first == pair.second
00457    for(EventPtrQueueIterator keyIterator = keyIteratorPair.first;
00458          keyIterator != keyIteratorPair.second; 
00459          ++keyIterator) {
00460 
00461       // If we iterator finds the pointer we want to delete,
00462       // then erase the element and return.
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    // See the Singleton design pattern for an explanation.
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 

Generated on Tue Dec 12 17:04:39 2006 for rfidsim by  doxygen 1.4.7