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