]> icculus.org git repositories - dana/openbox.git/blob - otk/timer.hh
make it shutdown on signals
[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 class OBTimerQueueManager {
106 private:
107   TimerQueue timerList;
108 public:
109   OBTimerQueueManager() {}
110   virtual ~OBTimerQueueManager() {}
111
112   //! Will wait for and fire the next timer in the queue.
113   /*!
114     The function will stop waiting if an event is received from the X server.
115   */
116   virtual void fire();
117   
118   virtual void addTimer(OBTimer* timer);
119   virtual void removeTimer(OBTimer* timer);
120 };
121
122 }
123
124 #endif // _BLACKBOX_Timer_hh