all repos — openbox @ c5f62494f14629797c109acc0b3048203a1adb6a

openbox fork - make it a bit more like ryudo

src/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
// -*- 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 ob {

// forward declaration
class OBTimerQueueManager;

class TimeoutHandler {
public:
  virtual void timeout(void) = 0;
};

class BTimer {
private:
  OBTimerQueueManager *manager;
  TimeoutHandler *handler;
  bool timing, recur;

  timeval _start, _timeout;

  BTimer(const BTimer&);
  BTimer& operator=(const BTimer&);

public:
  BTimer(OBTimerQueueManager *m, TimeoutHandler *h);
  virtual ~BTimer(void);

  void fireTimeout(void);

  inline bool isTiming(void) const { return timing; }
  inline bool isRecurring(void) const { return recur; }

  inline const timeval &getTimeout(void) const { return _timeout; }
  inline const timeval &getStartTime(void) const { return _start; }

  timeval timeRemaining(const timeval &tm) const;
  bool shouldFire(const timeval &tm) const;
  timeval endpoint(void) const;

  inline void recurring(bool b) { recur = b; }

  void setTimeout(long t);
  void setTimeout(const timeval &t);

  void start(void);  // manager acquires timer
  void stop(void);   // manager releases timer
  void halt(void);   // halts the timer

  bool operator<(const BTimer& 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(void): _Base() {}
  ~_timer_queue(void) {}

  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(void) const { return _Base::empty(); }
  size_t size(void) const { return _Base::size(); }
  void push(const _Tp& value) { _Base::push(value); }
  void pop(void) { _Base::pop(); }
  const _Tp& top(void) const { return _Base::top(); }
private:
  // no copying!
  _timer_queue(const _timer_queue&) {}
  _timer_queue& operator=(const _timer_queue&) {}
};

struct TimerLessThan {
  bool operator()(const BTimer* const l, const BTimer* const r) const {
    return *r < *l;
  }
};

typedef _timer_queue<BTimer*, std::vector<BTimer*>, TimerLessThan> TimerQueue;

class OBTimerQueueManager {
private:
  TimerQueue timerList;
public:
  OBTimerQueueManager() {}
  virtual ~OBTimerQueueManager() {}
  
  virtual void go();
  
  virtual void addTimer(BTimer* timer);
  virtual void removeTimer(BTimer* timer);
};

}

#endif // _BLACKBOX_Timer_hh