all repos — openbox @ 8152d453298bc3747ddcdcfa645b33afae7dc10e

openbox fork - make it a bit more like ryudo

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
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
#ifndef   __timer_hh
#define   __timer_hh

/*! @file timer.hh
  @brief Contains the Timer class, used for timed callbacks.
*/

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 <vector>

namespace otk {

//! The Timer class implements timed callbacks.
/*!
  The Timer class can be used to have a callback fire after a given time
  interval. A created Timer will fire repetitively until it is destroyed.
*/
class Timer {
public:
  //! Data type of Timer callback
  typedef void (*TimeoutHandler)(void *data);

private:
  //! Compares two timeval structs
  struct TimerCompare {
     //! Compares two timeval structs
     inline bool operator()(const Timer *a, const Timer *b) const {
       return timercmp(&a->_timeout, &b->_timeout, >);
     }
  };

  typedef
  std::priority_queue<Timer*, std::vector<Timer*>, TimerCompare> TimerQ;

  //! Milliseconds between timer firings
  long _delay;
  //! Callback for timer expiry
  TimeoutHandler _action;
  //! Data sent to callback
  void *_data;
  //! We overload the delete operator to just set this to true
  bool _del_me;
  //! The time the last fire should've been at
  struct timeval _last;
  //! When this timer will next trigger
  struct timeval _timeout;

  //! Queue of pending timers
  static TimerQ _q;
  //! Time next timer will expire
  static timeval _nearest_timeout;
  //! Time at start of current processing loop
  static timeval _now;

  //! Really delete something (not just flag for later)
  /*!
    @param self Timer to be deleted.
  */
  static void realDelete(Timer *self);

  //! Adds a millisecond delay to a timeval structure
  /*!
    @param a Amount of time to increment.
    @param msec Number of milliseconds to increment by.
  */
  static void timevalAdd(timeval &a, long msec);

public:
  //! Constructs a new running timer and queues it
  /*!
    @param delay Time in milliseconds between firings
    @param cb The function to be called on fire.
    @param data Data to be passed to the callback on fire.
  */
  Timer(long delay, TimeoutHandler cb, void *data);

  //! Overloaded delete so we can leave deleted objects in queue for later reap
  /*!
    @param self Pointer to current instance of Timer.
  */
  void operator delete(void *self);

  //! Dispatches all elligible timers, then optionally waits for X events
  /*!
    @param wait Whether to wait for X events after processing timers.
  */
  static void dispatchTimers(bool wait = true);

  //! Returns a relative timeval (to pass select) of the next timer
  /*!
    @param tm Changed to hold the time until next timer.
    @return true if there are any timers queued, and the timeout is being
            returned in 'tm'. false if there are no timers queued.
  */
  static bool nearestTimeout(struct timeval &tm);

  //! Initializes internal data before use
  static void initialize(void);

  //! Deletes all waiting timers
  static void destroy(void);
};

}

#endif // __timer.hh