TimerCore.cc

00001 #include "TimerCore.h"
00002 #include "Timer.h"
00003 
00004 #include <assert.h>
00005 
00006 //Define_Module_Like(TimerCore,Trivial);
00007 
00008 void TimerCore::checkExists(unsigned int index)
00009 {
00010   if (timers->find(index)==timers->end())
00011     error(" timer index %u doesn't exist", index);
00012 }
00013 
00014 void TimerCore::handleMessage(cMessage* msg)
00015 {
00016   assert(msg->isSelfMessage());
00017   //simulation.setContextModule(timer->owner);  
00018   timer->handleTimer(msg->getKind());
00019 }
00020 
00021 void TimerCore::init(Timer *owner)
00022 {
00023   timer = owner;
00024   timers = new std::map<unsigned int,cMessage *>();
00025   destructors = new std::map<unsigned int,cleanup *>();
00026 }
00027 
00028 unsigned int TimerCore::setTimer(simtime_t when)
00029 {
00030   unsigned int key = timers->size();
00031   while (timers->find(key)!=timers->end())
00032     key++;
00033   setTimer(key,when);
00034   return key;
00035 }
00036 
00037 void TimerCore::setTimer(unsigned int index, simtime_t when)
00038 {
00039   Enter_Method_Silent();
00040   cMessage *timer;
00041   if (timers->find(index)==timers->end())
00042   {
00043     timer = new cMessage("timer");
00044     timer->setKind(index);
00045     (*timers)[index] = timer;
00046     (*destructors)[index] = NULL;
00047   }
00048   else
00049   {
00050     timer = (*timers)[index];
00051     if (timer->isScheduled())
00052       cancelEvent(timer);
00053   }
00054 
00055   scheduleAt(simTime() + when, timer);  
00056 }
00057 
00058 void TimerCore::cancelTimer(unsigned int index)
00059 {
00060   Enter_Method_Silent();
00061   checkExists(index);
00062   if ((*timers)[index]->isScheduled())
00063     cancelEvent((*timers)[index]);
00064 }
00065 
00066 float TimerCore::remainingTimer(unsigned int index)
00067 {
00068   checkExists(index);
00069   if ((*timers)[index]->isScheduled())
00070     return SIMTIME_DBL((*timers)[index]->getArrivalTime()-simTime());
00071   else
00072     return -1;
00073 }
00074 
00075 void TimerCore::setContextDestructor(unsigned int index, cleanup *c)
00076 {
00077   checkExists(index);
00078   (*destructors)[index] = c;
00079 }
00080 
00081 TimerCore::~TimerCore()
00082 {
00083   for (std::map<unsigned int,cMessage*>::const_iterator p=timers->begin();p!=timers->end();p++)
00084   {
00085     unsigned int index = p->second->getKind();
00086     checkExists(index);
00087     if ((*timers)[index]->isScheduled())
00088     {
00089       if ((*destructors)[index]!=NULL)
00090         (*destructors)[index](contextPointer(index));
00091       cancelEvent((*timers)[index]);
00092     }
00093     delete p->second;
00094   }
00095   delete timers;
00096   delete destructors;
00097 }
00098 
00103 void TimerCore::setContextPointer(unsigned int index,void * data)
00104 {
00105   checkExists(index);
00106   (*timers)[index]->setContextPointer(data);
00107 }
00108 
00113 void * TimerCore::contextPointer(unsigned int index)
00114 {
00115   checkExists(index);
00116   return (*timers)[index]->getContextPointer();
00117 }
00118 
00119 /* Mark the first @count pointer ids (from 0 to @count-1) as allocated, so they don't get
00120  * auto-allocated by setTimer
00121  * @param count Number of timers to allocate
00122  */
00123 void TimerCore::allocateTimers(unsigned int count)
00124 {
00125   Enter_Method_Silent();
00126   for (unsigned int i=0;i<count;i++)
00127   {
00128     cMessage *timer;
00129     if (timers->find(i)==timers->end())
00130     {
00131       timer = new cMessage("timer");
00132       timer->setKind(i);
00133       (*timers)[i] = timer;
00134     }
00135   }
00136 }
00137 
00138 /* Delete a timer. Useful for auto-allocated timers that you don't need any more to 
00139  * reduce memory usage. Does nothing if the timer doesn't exist
00140  * @param index Timer to wipe
00141  */
00142 void TimerCore::deleteTimer(unsigned int index)
00143 {
00144   if (timers->find(index)!=timers->end())
00145   {
00146     cancelTimer(index);
00147     delete timers->find(index)->second;
00148     timers->erase(timers->find(index));
00149   }
00150 }
00151