]>
Dogcows Code - chaz/yoink/blob - src/moof/timer.hh
edd1de2deaf2cab1a98eff1502dffb0802efed86
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
8 *****************************************************************************/
10 #ifndef _MOOF_TIMER_HH_
11 #define _MOOF_TIMER_HH_
15 * Functions for measuring time in a friendly unit.
18 #include <boost/bind.hpp>
19 #include <boost/function.hpp>
20 #include <boost/noncopyable.hpp>
22 #include <moof/hash.hh>
23 #include <moof/math.hh>
29 // forward declarations
33 * A timer source is an object that keeps track of increasing time in units
34 * of seconds. A timer source does not necessarily have to increment at
35 * the same rate or in the same way as the real time. The time source must
36 * begin at zero and always remain the same or increase each time the time
44 * Deconstruct a timer source.
46 virtual ~timer_source() {}
49 * Get the number seconds since the timer source was created or reset.
51 virtual scalar
ticks() const = 0;
54 * Reset the timer such that the current time will become zero.
56 virtual void reset() = 0;
59 * Scale the time. After calling this, the timer source should either
60 * increment faster or slower, depending on the scale factor.
62 virtual void scale(scalar factor
) = 0;
67 * A class to represent a timer for scheduled events. The timer events
68 * will be executed on or sometime after their schedculed time. The
69 * runloop associated with the current running view will make an attempt to
70 * fire any expired timers as close to their scheduled times as possible.
72 class timer
: public boost::noncopyable
77 * A type for the state of a timer.
81 invalid
= 0, /// Timer is not scheduled.
82 relative
= 1, /// Timer is scheduled by a relative time.
83 absolute
= 2, /// Timer is scheduled by an absolute time.
84 repeat
= 3 /// Timer is scheduled by a periodic time.
88 * Function protocol for a timer event handler. A function matching
89 * this protocol will be called when the timer expires. The function
90 * takes two parameters: the timer object that just expired, and the
91 * absolute time of the time source which caused the timer to expire.
93 typedef boost::function
<void(timer
&,scalar
)> function
;
96 * Construct an invalid (uninitialized) timer.
100 absolute_(SCALAR(0.0)),
104 * Construct a scheduled timer.
105 * \param function The event handler.
106 * \param seconds The number of seconds; the meaning of this depends on
107 * the mode of the timer.
108 * \param mode The timer mode. If the mode is relative (default), the
109 * seconds parameter is the number of seconds from the current time to
110 * wait before expiring the timer. If the mode is absolute, the
111 * seconds parameter is the number of seconds from some arbitrary,
112 * fixed time in the past. If the mode is repeat, the seconds
113 * parameter is the number of seconds from now to wait before expiring
114 * the timer, at which time the timer will be rescheduled to expired
115 * again at that many seconds from the expiration time. A repeating
116 * timer can be invalidated manually using invalidate().
118 timer(const function
& function
,
120 mode mode
= relative
,
121 timer_source
& source
= default_source()) :
124 init(function
, seconds
, mode
, source
);
128 * Deconstruct a timer. This will automagically invalidate the timer,
129 * so it will not expire or fire an event.
134 * Initialize a timer with a scheduled time. If the timer is already
135 * scheduled, its prior schedule will be invalidated and replaced by
137 * \param function The event handler.
138 * \param seconds The number of seconds; the meaning of this depends on
139 * the mode of the timer.
140 * \param mode The timer mode. If the mode is relative (default), the
141 * seconds parameter is the number of seconds from the current time to
142 * wait before expiring the timer. If the mode is absolute, the
143 * seconds parameter is the number of seconds from some arbitrary,
144 * fixed time in the past. If the mode is repeat, the seconds
145 * parameter is the number of seconds from now to wait before expiring
146 * the timer, at which time the timer will be rescheduled to expired
147 * again at that many seconds from the expiration time. A repeating
148 * timer can be invalidated manually using invalidate().
150 void init(const function
& function
,
152 enum mode mode
= relative
,
153 timer_source
& source
= default_source());
156 * Manually invalidated the timer, removing any schedule such that the
157 * timer will not expired and no event will be fired.
161 enum mode
mode() const
167 * Manually fire the timer event. Usually, the timer event will be
168 * fired when the timer expires, but this can be used to fire it
169 * prematurely. If the timer is scheduled, it will be invalidated. If
170 * the timer is already invalid (but is initialized with an event
171 * handler), the event will be fired and the timer will remain invalid.
172 * \param t The absolute time passed to the timer event function.
177 fire(source_
->ticks());
181 * Fire the timer event if it is expired.
182 * \param t The absolute time used as a reference to determine if the
183 * timer is expired; defaults to the current time.
184 * \return The absolute time of the next expiration (if repeating), or
187 bool fire_if_expired(scalar t
)
196 bool fire_if_expired()
198 return fire_if_expired(source_
->ticks());
202 * Get the absolute time of the next expiration of this timer.
205 scalar
expiration() const
211 * Get the number of seconds remaining before the timer is scheduled to
212 * expired. If the timer is invalid, the retured value will be
214 * \param t The absolute time used as a reference to determine the
215 * amount of time left; defaults to the current time.
218 scalar
remaining(scalar t
) const
220 return expiration() - t
;
222 scalar
remaining() const
224 return remaining(source_
->ticks());
228 * Get whether or not the timer is expired. A timer on a repeating
229 * schedule will never be expired since it will always have a scheduled
230 * expiration time in the future. If the timer is expired but not
231 * invalid, the timer event has not yet fired; the timer will be
232 * invalidated when it does fire.
233 * \param t The absolute time used as a reference to determine if the
234 * timer is expired; defaults to the current time.
235 * \return True if the timer is expired, false otherwise.
237 bool is_expired(scalar t
) const
239 return remaining(t
) < SCALAR(0.0);
241 bool is_expired() const
243 return is_expired(source_
->ticks());
246 static timer_source
& default_source();
249 * Get the number of real seconds since the default timer was first
250 * created or last reset.
253 static scalar
ticks();
256 * Put the thread to sleep for a certain period of time. If absolute
257 * is true, then it will sleep until the default timer reaches the
258 * specified number of seconds. If the mode is relative, the thread
259 * will sleep for that many seconds. Unlike system sleep functions,
260 * this one automatically resumes sleep if sleep was interrupted by a
261 * signal. Therefore, calling this function is guaranteed to sleep for
262 * at least the requested amount of time.
263 * \param seconds Number of seconds.
264 * \param mode The timer mode.
266 static void sleep(scalar seconds
, enum mode mode
= relative
);
270 void added_to_runloop(runloop
& runloop
);
271 void detach_from_runloop();
277 timer_source
* source_
;
282 class game_time
: public timer_source
286 game_time(scalar timestep
= SCALAR(1.0)) :
288 scalefactor_(SCALAR(1.0))
295 return reference_
+ scalar(ticks_
) * scale_
;
300 reference_
= SCALAR(0.0);
303 void reset(scalar timestep
)
306 timestep_
= timestep
;
307 scale_
= timestep_
* scalefactor_
;
310 void scale(scalar factor
)
312 reference_
= ticks();
314 scale_
= timestep_
* factor
;
315 scalefactor_
= factor
;
318 scalar
step(unsigned step
= 1)
336 #endif // _MOOF_TIMER_HH_
This page took 0.050815 seconds and 3 git commands to generate.