3ec4ef9d8e04bd23a1e6141d4c242e430f6d0d5e
[chaz/yoink] / src / moof / timer.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #ifndef _MOOF_TIMER_HH_
13 #define _MOOF_TIMER_HH_
14
15 /**
16 * \file timer.hh
17 * Functions for measuring time in a friendly unit.
18 */
19
20 #include <boost/bind.hpp>
21 #include <boost/function.hpp>
22 #include <boost/noncopyable.hpp>
23
24 #include <moof/hash.hh>
25 #include <moof/math.hh>
26
27
28 namespace moof {
29
30
31 /**
32 * A class to represent a timer for scheduled events. The timer events
33 * will be executed on or sometime after their schedculed time. The
34 * runloop associated with the current running view will make an attempt to
35 * fire any expired timers as close to their scheduled times as possible.
36 */
37 class timer : public boost::noncopyable
38 {
39 public:
40
41 /**
42 * A type for the state of a timer.
43 */
44 enum mode
45 {
46 invalid = -1, /// Timer is not scheduled.
47 relative = 0, /// Timer is scheduled by a relative time.
48 absolute = 1, /// Timer is scheduled by an absolute time.
49 repeat = 2 /// Timer is scheduled by a periodic time.
50 };
51
52 /**
53 * Function protocol for a timer event handler. A function matching
54 * this protocol will be called when the timer expires. The function
55 * takes two parameters: the timer object that just expired, and the
56 * absolute time.
57 */
58 typedef boost::function<void(timer&,scalar)> function;
59
60
61 /**
62 * Construct an invalid (uninitialized) timer.
63 */
64 timer() :
65 mode_(invalid),
66 absolute_(SCALAR(0.0)) {}
67
68 /**
69 * Construct a scheduled timer.
70 * \param function The event handler.
71 * \param seconds The number of seconds; the meaning of this depends on
72 * the mode of the timer.
73 * \param mode The timer mode. If the mode is relative (default), the
74 * seconds parameter is the number of seconds from the current time to
75 * wait before expiring the timer. If the mode is absolute, the
76 * seconds parameter is the number of seconds from some arbitrary,
77 * fixed time in the past. If the mode is repeat, the seconds
78 * parameter is the number of seconds from now to wait before expiring
79 * the timer, at which time the timer will be rescheduled to expired
80 * again at that many seconds from the expiration time. A repeating
81 * timer can be invalidated manually using invalidate().
82 */
83 timer(const function& function, scalar seconds, mode mode = relative)
84 {
85 init(function, seconds, mode);
86 }
87
88 /**
89 * Deconstruct a timer. This will automagically invalidate the timer,
90 * so it will not expire or fire an event.
91 */
92 ~timer()
93 {
94 invalidate();
95 }
96
97
98 /**
99 * Initialize a timer with a scheduled time. If the timer is already
100 * scheduled, its prior schedule will be invalidated and replaced by
101 * this new schedule.
102 * \param function The event handler.
103 * \param seconds The number of seconds; the meaning of this depends on
104 * the mode of the timer.
105 * \param mode The timer mode. If the mode is relative (default), the
106 * seconds parameter is the number of seconds from the current time to
107 * wait before expiring the timer. If the mode is absolute, the
108 * seconds parameter is the number of seconds from some arbitrary,
109 * fixed time in the past. If the mode is repeat, the seconds
110 * parameter is the number of seconds from now to wait before expiring
111 * the timer, at which time the timer will be rescheduled to expired
112 * again at that many seconds from the expiration time. A repeating
113 * timer can be invalidated manually using invalidate().
114 */
115 void init(const function& function,
116 scalar seconds,
117 mode mode = relative);
118
119
120 /**
121 * Get whether or not the timer is valid. If a timer is valid, it is
122 * still scheduled to expired. You can get the time remaining from
123 * seconds_remaining().
124 */
125 bool is_valid() const;
126
127 /**
128 * Manually invalidated the timer, removing any schedule such that the
129 * timer will not expired and no event will be fired.
130 */
131 void invalidate();
132
133
134 /**
135 * Manually fire the timer event. Usually, the timer event will be
136 * fired when the timer expires, but this can be used to fire it
137 * prematurely. If the timer is scheduled, it will be invalidated. If
138 * the timer is already invalid (but is initialized with an event
139 * handler), the event will be fired and the timer will remain invalid.
140 */
141 void fire();
142
143
144 /**
145 * Get the number of seconds remaining before the timer is scheduled to
146 * expired. If the timer is invalid, the retured value will be
147 * negative.
148 * \return Seconds.
149 */
150 scalar seconds_remaining() const;
151
152 /**
153 * Get the absolute time of the next expiration of this timer.
154 * \return Seconds.
155 */
156 scalar next_expiration() const;
157
158
159 /**
160 * Get whether or not the timer is expired. A timer on a repeating
161 * schedule will never be expired since it will always have a scheduled
162 * expiration time in the future. If the timer is expired but not
163 * invalid, the timer event has not yet fired; the timer will be
164 * invalidated when it does fire.
165 * \return True if the timer is expired, false otherwise.
166 */
167 bool is_expired() const;
168
169 /**
170 * Get whether or not the timer is on a repeating schedule.
171 * \return True if the timer is repeating, false otherwise.
172 */
173 bool is_repeating() const;
174
175
176 /**
177 * Get the number of seconds since a fixed, arbitrary point in the
178 * past.
179 * \return Seconds.
180 */
181 static scalar ticks();
182
183
184 /**
185 * Put the thread to sleep for a certain period of time. If absolute
186 * is true, then it will sleep until seconds after the fixed time in
187 * the past. If absolute is false, it will sleep for seconds starting
188 * now. Unlike system sleep functions, this one automatically resumes
189 * sleep if sleep was interrupted by a signal. Therefore, calling this
190 * function is guaranteed to sleep for the requested amount of time
191 * (and maybe longer).
192 * \param seconds Number of seconds.
193 * \param mode The timer mode.
194 */
195 static void sleep(scalar seconds, mode mode = relative);
196
197
198 /**
199 * Get the absolute time when the next timer is scheduled to expire.
200 * \return Absolute time, in seconds.
201 */
202 static scalar next_event()
203 {
204 return next_event_;
205 }
206
207
208 /**
209 * Fire any timers which are not yet invalidated but have an expiration
210 * time in the past.
211 */
212 static void fire_expired_timers()
213 {
214 fire_expired_timers(ticks());
215 }
216
217 /**
218 * Fire any timers which are not yet invalidated but have an expiration
219 * time before a given absolute time.
220 */
221 static void fire_expired_timers(scalar t);
222
223
224 private:
225
226 static unsigned new_identifier();
227 static scalar find_next_event();
228
229 function function_;
230 mode mode_;
231 scalar absolute_;
232 scalar interval_;
233 unsigned id_;
234
235 static scalar next_event_;
236 static hash<unsigned,timer*,hash_function> timers_;
237 };
238
239
240 } // namespace moof
241
242 #endif // _MOOF_TIMER_HH_
243
This page took 0.037399 seconds and 3 git commands to generate.