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