otk/timer.hh (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
// -*- mode: C++; indent-tabs-mode: nil; -*- #ifndef _BLACKBOX_Timer_hh #define _BLACKBOX_Timer_hh extern "C" { #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else // !TIME_WITH_SYS_TIME # ifdef HAVE_SYS_TIME_H # include <sys/time.h> # else // !HAVE_SYS_TIME_H # include <time.h> # endif // HAVE_SYS_TIME_H #endif // TIME_WITH_SYS_TIME } #include <queue> #include <algorithm> #include <vector> namespace otk { // forward declaration class OBTimerQueueManager; typedef void *OBTimeoutData; typedef void (*OBTimeoutHandler)(OBTimeoutData); class OBTimer { private: OBTimerQueueManager *manager; OBTimeoutHandler handler; OBTimeoutData data; bool timing, recur; timeval _start, _timeout; OBTimer(const OBTimer&); OBTimer& operator=(const OBTimer&); public: OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d); virtual ~OBTimer(); void fireTimeout(); inline bool isTiming() const { return timing; } inline bool isRecurring() const { return recur; } inline const timeval &getTimeout() const { return _timeout; } inline const timeval &getStartTime() const { return _start; } timeval timeRemaining(const timeval &tm) const; bool shouldFire(const timeval &tm) const; timeval endpoint() const; inline void recurring(bool b) { recur = b; } void setTimeout(long t); void setTimeout(const timeval &t); void start(); // manager acquires timer void stop(); // manager releases timer void halt(); // halts the timer bool operator<(const OBTimer& other) const { return shouldFire(other.endpoint()); } }; template <class _Tp, class _Sequence, class _Compare> class _timer_queue: protected std::priority_queue<_Tp, _Sequence, _Compare> { public: typedef std::priority_queue<_Tp, _Sequence, _Compare> _Base; _timer_queue(): _Base() {} ~_timer_queue() {} void release(const _Tp& value) { c.erase(std::remove(c.begin(), c.end(), value), c.end()); // after removing the item we need to make the heap again std::make_heap(c.begin(), c.end(), comp); } bool empty() const { return _Base::empty(); } size_t size() const { return _Base::size(); } void push(const _Tp& value) { _Base::push(value); } void pop() { _Base::pop(); } const _Tp& top() const { return _Base::top(); } private: // no copying! _timer_queue(const _timer_queue&) {} _timer_queue& operator=(const _timer_queue&) {} }; struct TimerLessThan { bool operator()(const OBTimer* const l, const OBTimer* const r) const { return *r < *l; } }; typedef _timer_queue<OBTimer*, std::vector<OBTimer*>, TimerLessThan> TimerQueue; //! Manages a queue of OBTimer objects /*! All OBTimer objects add themself to an OBTimerQueueManager. The manager is what fires the timers when their time has elapsed. This is done by having the application call the OBTimerQueueManager::fire class in its main event loop. */ class OBTimerQueueManager { private: //! A priority queue of all timers being managed by this class. TimerQueue timerList; public: //! Constructs a new OBTimerQueueManager OBTimerQueueManager() {} //! Destroys the OBTimerQueueManager virtual ~OBTimerQueueManager() {} //! Will wait for and fire the next timer in the queue. /*! The function will stop waiting if an event is received from the X server. */ virtual void fire(); //! Adds a new timer to the queue /*! @param timer An OBTimer to add to the queue */ virtual void addTimer(OBTimer* timer); //! Removes a timer from the queue /*! @param timer An OBTimer already in the queue to remove */ virtual void removeTimer(OBTimer* timer); }; } #endif // _BLACKBOX_Timer_hh |