big fat commit..
[mikachu/openbox.git] / src / 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 // forward declaration
19 class TimerQueueManager;
20
21 class TimeoutHandler {
22 public:
23   virtual void timeout(void) = 0;
24 };
25
26 class BTimer {
27 private:
28   TimerQueueManager *manager;
29   TimeoutHandler *handler;
30   bool timing, recur;
31
32   timeval _start, _timeout;
33
34   BTimer(const BTimer&);
35   BTimer& operator=(const BTimer&);
36
37 public:
38   BTimer(TimerQueueManager *m, TimeoutHandler *h);
39   virtual ~BTimer(void);
40
41   void fireTimeout(void);
42
43   inline bool isTiming(void) const { return timing; }
44   inline bool isRecurring(void) const { return recur; }
45
46   inline const timeval &getTimeout(void) const { return _timeout; }
47   inline const timeval &getStartTime(void) const { return _start; }
48
49   timeval timeRemaining(const timeval &tm) const;
50   bool shouldFire(const timeval &tm) const;
51   timeval endpoint(void) const;
52
53   inline void recurring(bool b) { recur = b; }
54
55   void setTimeout(long t);
56   void setTimeout(const timeval &t);
57
58   void start(void);  // manager acquires timer
59   void stop(void);   // manager releases timer
60   void halt(void);   // halts the timer
61
62   bool operator<(const BTimer& other) const
63   { return shouldFire(other.endpoint()); }
64 };
65
66
67 #include <queue>
68 #include <algorithm>
69
70 template <class _Tp, class _Sequence, class _Compare>
71 class _timer_queue: protected std::priority_queue<_Tp, _Sequence, _Compare> {
72 public:
73   typedef std::priority_queue<_Tp, _Sequence, _Compare> _Base;
74
75   _timer_queue(void): _Base() {}
76   ~_timer_queue(void) {}
77
78   void release(const _Tp& value) {
79     c.erase(std::remove(c.begin(), c.end(), value), c.end());
80     // after removing the item we need to make the heap again
81     std::make_heap(c.begin(), c.end(), comp);
82   }
83   bool empty(void) const { return _Base::empty(); }
84   size_t size(void) const { return _Base::size(); }
85   void push(const _Tp& value) { _Base::push(value); }
86   void pop(void) { _Base::pop(); }
87   const _Tp& top(void) const { return _Base::top(); }
88 private:
89   // no copying!
90   _timer_queue(const _timer_queue&) {}
91   _timer_queue& operator=(const _timer_queue&) {}
92 };
93
94 struct TimerLessThan {
95   bool operator()(const BTimer* const l, const BTimer* const r) const {
96     return *r < *l;
97   }
98 };
99
100 #include <vector>
101 typedef _timer_queue<BTimer*, std::vector<BTimer*>, TimerLessThan> TimerQueue;
102
103 class TimerQueueManager {
104 public:
105   virtual void addTimer(BTimer* timer) = 0;
106   virtual void removeTimer(BTimer* timer) = 0;
107 };
108
109 #endif // _BLACKBOX_Timer_hh