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