Timer.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #include "Error.h"
00008 
00009 #include "Timer.h"
00010 
00011 Timer::SingleShotList Timer::_singleShots;
00012 Timer::TimerList Timer::_timers;
00013 
00014 // Public methods.
00015 
00016 Timer::Timer(const unsigned int msTime, const bool periodical) : Object()
00017 {
00018   _msTime = msTime;
00019   _periodical = periodical;
00020   _lastShotTimestamp.tv_sec = 0;
00021   _lastShotTimestamp.tv_usec = 0;
00022   _timers.insert(this);
00023 }
00024 
00025 Timer::~Timer()
00026 {
00027   TimerList::iterator f = _timers.find(this);
00028   if (f == _timers.end())
00029     ERROR(MSG_INTEGRITY_FAILURE);
00030   else
00031     _timers.erase(f);
00032 }
00033 
00034 int Timer::setPeriodical(const bool yes)
00035 {
00036   _periodical = yes;
00037   return OK;
00038 }
00039 
00040 bool Timer::periodical() const
00041 {
00042   return _periodical;
00043 }
00044 
00045 int Timer::setTime(const unsigned int msTime)
00046 {
00047   _msTime = msTime;
00048   return OK;
00049 }
00050 
00051 unsigned int Timer::time() const
00052 {
00053   return _msTime;
00054 }
00055 
00056 int Timer::singleShot(const unsigned int msTime, Object *slotObject, SlotMethod slotMethod)
00057 {
00058   if (!slotObject || !slotMethod)
00059     return ERROR(MSG_NULL_POINTER);
00060 
00061   struct timeval timestamp;
00062 
00063   if (gettimeofday(&timestamp, NULL) < 0)
00064     return ERROR(MSG_TIMER_CANNOT_GET_TIME, strerror(errno));
00065 
00066   SingleShot timer = {msTime, slotObject->id(), slotMethod, timestamp};
00067 
00068   _singleShots.push_back(timer);
00069 
00070   return OK;
00071 }
00072 
00073 int Timer::suspend()
00074 {
00075   if (suspended())
00076     return OK;
00077 
00078   int res;
00079 
00080   if (FAILED(res = Object::suspend()))
00081     return ERROR_BACKTRACE(res);
00082 
00083   EMIT(suspended);
00084 
00085   return OK;
00086 }
00087 
00088 int Timer::resume()
00089 {
00090   if (!suspended())
00091     return OK;
00092 
00093   int res;
00094 
00095   if (FAILED(res = Object::resume()))
00096     return ERROR_BACKTRACE(res);
00097 
00098   EMIT(resumed);
00099 
00100   return OK;
00101 }
00102 
00103 unsigned int Timer::sinceShot() const
00104 {
00105   return since(_lastShotTimestamp);
00106 }
00107 
00108 unsigned int Timer::tillShot() const
00109 {
00110   if (!_periodical && (_lastShotTimestamp.tv_sec != 0 || _lastShotTimestamp.tv_usec != 0))
00111     return 0;
00112   int delta = _msTime - sinceShot();
00113 
00114   return delta < 0 ? 0 : delta;
00115 }
00116 
00117 bool Timer::ready() const
00118 {
00119   if (!_periodical && (_lastShotTimestamp.tv_sec != 0 || _lastShotTimestamp.tv_usec != 0) ||
00120       sinceShot() < _msTime)
00121     return false;
00122 
00123   return true;
00124 }
00125 
00126 int Timer::list(String &text)
00127 {
00128   TimerList::const_iterator i = _timers.begin();
00129   TimerList::const_iterator e = _timers.end();
00130   String line;
00131   unsigned int n = 1;
00132 
00133   line.sprintf("%s%6s\t%6s\t%10s\t%10s\t%10s\t%10s\t%5s\t%9s%s", String::eol(),
00134                "#", "ID", "TIME", "PERIODICAL", "SINCESHOT", "TOSHOT", "READY", "SUSPENDED", String::eol());
00135   text = TIMER_COLOR_TITLE(line);
00136   while (i != e) {
00137     line.sprintf("%6d\t%6llu\t%10u\%10s\t%10u\t%10u\t%5s\t%9s%s",
00138       n, (*i)->id(), (*i)->time(), (*i)->periodical() ? "Yes" : "No", (*i)->sinceShot(), (*i)->tillShot(),
00139       (*i)->ready() ? "Yes" : "No", (*i)->suspended() ? "Yes" : "No", String::eol());
00140     text += line;
00141     ++i;
00142     ++n;
00143   }
00144 
00145   return OK;
00146 }
00147 
00148 int Timer::listSingleShot(String &text)
00149 {
00150   SingleShotList::const_iterator i = _singleShots.begin();
00151   SingleShotList::const_iterator e = _singleShots.end();
00152   String line;
00153   unsigned int n = 1;
00154   unsigned int sinceTime;
00155   int tillShot;
00156 
00157   line.sprintf("%s%6s\t%10s\t%10s\t%10s\t%6s%s", String::eol(), "#", "TIME", "SINCESHOT", "TOSHOT", "SLOTID", String::eol());
00158   text = TIMER_COLOR_TITLE(line);
00159   while (i != e) {
00160     sinceTime = since(i->firedTimestamp);
00161     tillShot = i->msTime - sinceTime;
00162     line.sprintf("%6d\t%10u\t%10u\%10u\t%6llu%s",
00163       n, i->msTime, sinceTime, tillShot > 0 ? tillShot : 0, i->slotObjectId, String::eol());
00164     text += line;
00165     ++i;
00166     ++n;
00167   }
00168 
00169   return OK;
00170 }
00171 
00172 // Private methods.
00173 
00174 int Timer::shoot()
00175 {
00176   if (suspended() || !ready())
00177     return OK;
00178 
00179   if (gettimeofday(&_lastShotTimestamp, NULL) < 0)
00180     return ERROR(MSG_TIMER_CANNOT_GET_TIME, strerror(errno));
00181 
00182   EMIT(shot);
00183 
00184   return OK;
00185 }
00186 
00187 int Timer::singleShoot()
00188 {
00189   if (_singleShots.empty())
00190     return OK;
00191 
00192   SingleShotList::iterator i = _singleShots.begin();
00193   SingleShotList::iterator e = _singleShots.end();
00194   vector<SingleShotList::iterator> indexes;
00195   Object *obj;
00196   int res;
00197 
00198   while (i != e) {
00199     if (since(i->firedTimestamp) >= i->msTime) {
00200       if (FAILED(res = Object::get(i->slotObjectId, &obj))) {
00201         ERROR_BACKTRACE(res);
00202         indexes.push_back(i);
00203       } else
00204           if (!obj->suspended()) {
00205             if (FAILED(res = (obj->*(i->slotMethod))()))
00206               ERROR_BACKTRACE(res);
00207             indexes.push_back(i);
00208           }
00209     }
00210     ++i;
00211   }
00212 
00213   unsigned int j, size = indexes.size();
00214   for (j = 0; j < size; ++j)
00215     _singleShots.erase(indexes[j]);
00216 
00217   return OK;
00218 }
00219 
00220 unsigned int Timer::since(const struct timeval &timestamp)
00221 {
00222   struct timeval tv, delta;
00223 
00224   if (gettimeofday(&tv, NULL) < 0)
00225     return ERROR(MSG_TIMER_CANNOT_GET_TIME, strerror(errno));
00226 
00227   timersub(&tv, &timestamp, &delta);
00228 
00229   return delta.tv_sec * 1000 + delta.tv_usec / 1000;
00230 }
00231 
00232 int Timer::shootTimers()
00233 {
00234   if (_timers.empty())
00235     return OK;
00236 
00237   TimerList::iterator i = _timers.begin();
00238   TimerList::iterator e = _timers.end();
00239   int res;
00240 
00241   while (i != e) {
00242     if (FAILED(res = (*i)->shoot()))
00243       ERROR_BACKTRACE(res);
00244     ++i;
00245   }
00246   if (FAILED(res = singleShoot()))
00247     return ERROR_BACKTRACE(res);
00248 
00249   return OK;
00250 }

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1