]> icculus.org git repositories - mikachu/openbox.git/blob - otk/timer.hh
add comments
[mikachu/openbox.git] / otk / timer.hh
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 #ifndef   __timer_hh
3 #define   __timer_hh
4
5 /*! @file timer.hh
6   @brief Contains the Timer class, used for timed callbacks.
7 */
8
9 extern "C" {
10 #ifdef    TIME_WITH_SYS_TIME
11 #  include <sys/time.h>
12 #  include <time.h>
13 #else // !TIME_WITH_SYS_TIME
14 #  ifdef    HAVE_SYS_TIME_H
15 #    include <sys/time.h>
16 #  else // !HAVE_SYS_TIME_H
17 #    include <time.h>
18 #  endif // HAVE_SYS_TIME_H
19 #endif // TIME_WITH_SYS_TIME
20 }
21
22 #include <queue>
23 #include <vector>
24
25 namespace otk {
26
27 //! The Timer class implements timed callbacks.
28 /*!
29   The Timer class can be used to have a callback fire after a given time
30   interval. A created Timer will fire repetitively until it is destroyed.
31 */
32 class Timer {
33 public:
34   //! Data type of Timer callback
35   typedef void (*TimeoutHandler)(void *data);
36
37 private:
38   //! Compares two timeval structs
39   struct TimerCompare {
40      //! Compares two timeval structs
41      inline bool operator()(const Timer *a, const Timer *b) const {
42        return timercmp(&a->_timeout, &b->_timeout, >);
43      }
44   };
45   friend struct TimerCompare; // give access to _timeout for shitty compilers
46
47   typedef
48   std::priority_queue<Timer*, std::vector<Timer*>, TimerCompare> TimerQ;
49
50   //! Milliseconds between timer firings
51   long _delay;
52   //! Callback for timer expiry
53   TimeoutHandler _action;
54   //! Data sent to callback
55   void *_data;
56   //! We overload the delete operator to just set this to true
57   bool _del_me;
58   //! The time the last fire should've been at
59   struct timeval _last;
60   //! When this timer will next trigger
61   struct timeval _timeout;
62
63   //! Queue of pending timers
64   static TimerQ _q;
65   //! Time next timer will expire
66   static timeval _nearest_timeout;
67   //! Time at start of current processing loop
68   static timeval _now;
69
70   //! Really delete something (not just flag for later)
71   /*!
72     @param self Timer to be deleted.
73   */
74   static void realDelete(Timer *self);
75
76   //! Adds a millisecond delay to a timeval structure
77   /*!
78     @param a Amount of time to increment.
79     @param msec Number of milliseconds to increment by.
80   */
81   static void timevalAdd(timeval &a, long msec);
82
83 public:
84   //! Constructs a new running timer and queues it
85   /*!
86     @param delay Time in milliseconds between firings
87     @param cb The function to be called on fire.
88     @param data Data to be passed to the callback on fire.
89   */
90   Timer(long delay, TimeoutHandler cb, void *data);
91
92   //! Overloaded delete so we can leave deleted objects in queue for later reap
93   /*!
94     @param self Pointer to current instance of Timer.
95   */
96   void operator delete(void *self);
97
98   //! Dispatches all elligible timers, then optionally waits for X events
99   /*!
100     @param wait Whether to wait for X events after processing timers.
101   */
102   static void dispatchTimers(bool wait = true);
103
104   //! Returns a relative timeval (to pass select) of the next timer
105   /*!
106     @param tm Changed to hold the time until next timer.
107     @return true if there are any timers queued, and the timeout is being
108             returned in 'tm'. false if there are no timers queued.
109   */
110   static bool nearestTimeout(struct timeval &tm);
111
112   //! Initializes internal data before use
113   static void initialize(void);
114
115   //! Deletes all waiting timers
116   static void destroy(void);
117 };
118
119 }
120
121 #endif // __timer.hh