]>
Dogcows Code - chaz/yoink/blob - src/moof/timer.hh
9f3e9846096d7e09600a053ea929c66e7af91d19
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
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.
10 **************************************************************************/
12 #ifndef _MOOF_TIMER_HH_
13 #define _MOOF_TIMER_HH_
17 * Functions for measuring time in a friendly unit.
20 #include <boost/bind.hpp>
21 #include <boost/function.hpp>
22 #include <boost/noncopyable.hpp>
24 #include <moof/hash.hh>
25 #include <moof/math.hh>
32 * A timer source is an object that keeps track of increasing time in units
33 * of seconds. A timer source does not necessarily have to increment at
34 * the same rate or in the same way as the real time. The time source must
35 * begin at zero and always remain the same or increase each time the time
43 * Deconstruct a timer source.
45 virtual ~timer_source() {}
48 * Get the number seconds since the timer source was created or reset.
50 virtual scalar
ticks() const = 0;
53 * Reset the timer such that the current time will become zero.
55 virtual void reset() = 0;
58 * Scale the time. After calling this, the timer source should either
59 * increment faster or slower, depending on the scale factor.
61 virtual void scale(scalar factor
) = 0;
69 * A class to represent a timer for scheduled events. The timer events
70 * will be executed on or sometime after their schedculed time. The
71 * runloop associated with the current running view will make an attempt to
72 * fire any expired timers as close to their scheduled times as possible.
74 class timer
: public boost::noncopyable
79 * A type for the state of a timer.
83 invalid
= 0, /// Timer is not scheduled.
84 relative
= 1, /// Timer is scheduled by a relative time.
85 absolute
= 2, /// Timer is scheduled by an absolute time.
86 repeat
= 3 /// Timer is scheduled by a periodic time.
90 * Function protocol for a timer event handler. A function matching
91 * this protocol will be called when the timer expires. The function
92 * takes two parameters: the timer object that just expired, and the
95 typedef boost::function
<void(timer
&,scalar
)> function
;
99 * Construct an invalid (uninitialized) timer.
103 absolute_(SCALAR(0.0)),
107 * Construct a scheduled timer.
108 * \param function The event handler.
109 * \param seconds The number of seconds; the meaning of this depends on
110 * the mode of the timer.
111 * \param mode The timer mode. If the mode is relative (default), the
112 * seconds parameter is the number of seconds from the current time to
113 * wait before expiring the timer. If the mode is absolute, the
114 * seconds parameter is the number of seconds from some arbitrary,
115 * fixed time in the past. If the mode is repeat, the seconds
116 * parameter is the number of seconds from now to wait before expiring
117 * the timer, at which time the timer will be rescheduled to expired
118 * again at that many seconds from the expiration time. A repeating
119 * timer can be invalidated manually using invalidate().
121 timer(const function
& function
,
123 mode mode
= relative
,
124 timer_source
& source
= default_source()) :
127 init(function
, seconds
, mode
, source
);
132 * Deconstruct a timer. This will automagically invalidate the timer,
133 * so it will not expire or fire an event.
139 * Initialize a timer with a scheduled time. If the timer is already
140 * scheduled, its prior schedule will be invalidated and replaced by
142 * \param function The event handler.
143 * \param seconds The number of seconds; the meaning of this depends on
144 * the mode of the timer.
145 * \param mode The timer mode. If the mode is relative (default), the
146 * seconds parameter is the number of seconds from the current time to
147 * wait before expiring the timer. If the mode is absolute, the
148 * seconds parameter is the number of seconds from some arbitrary,
149 * fixed time in the past. If the mode is repeat, the seconds
150 * parameter is the number of seconds from now to wait before expiring
151 * the timer, at which time the timer will be rescheduled to expired
152 * again at that many seconds from the expiration time. A repeating
153 * timer can be invalidated manually using invalidate().
155 void init(const function
& function
,
157 enum mode mode
= relative
,
158 timer_source
& source
= default_source());
162 * Manually invalidated the timer, removing any schedule such that the
163 * timer will not expired and no event will be fired.
168 enum mode
mode() const
175 * Manually fire the timer event. Usually, the timer event will be
176 * fired when the timer expires, but this can be used to fire it
177 * prematurely. If the timer is scheduled, it will be invalidated. If
178 * the timer is already invalid (but is initialized with an event
179 * handler), the event will be fired and the timer will remain invalid.
180 * \param t The absolute time passed to the timer event function.
185 fire(source_
->ticks());
190 * Fire the timer event if it is expired.
191 * \param t The absolute time used as a reference to determine if the
192 * timer is expired; defaults to the current time.
193 * \return The absolute time of the next expiration (if repeating), or
196 scalar
fire_if_expired(scalar t
)
198 if (is_expired(t
)) fire(t
);
201 scalar
fire_if_expired()
203 return fire_if_expired(source_
->ticks());
208 * Get the absolute time of the next expiration of this timer.
211 scalar
expiration() const
217 * Get the number of seconds remaining before the timer is scheduled to
218 * expired. If the timer is invalid, the retured value will be
220 * \param t The absolute time used as a reference to determine the
221 * amount of time left; defaults to the current time.
224 scalar
remaining(scalar t
) const
226 return expiration() - t
;
228 scalar
remaining() const
230 return remaining(source_
->ticks());
235 * Get whether or not the timer is expired. A timer on a repeating
236 * schedule will never be expired since it will always have a scheduled
237 * expiration time in the future. If the timer is expired but not
238 * invalid, the timer event has not yet fired; the timer will be
239 * invalidated when it does fire.
240 * \param t The absolute time used as a reference to determine if the
241 * timer is expired; defaults to the current time.
242 * \return True if the timer is expired, false otherwise.
244 bool is_expired(scalar t
) const
246 return remaining(t
) < SCALAR(0.0);
248 bool is_expired() const
250 return is_expired(source_
->ticks());
254 static timer_source
& default_source();
257 * Get the number of real seconds since the default timer was first
258 * created or last reset.
261 static scalar
ticks();
265 * Put the thread to sleep for a certain period of time. If absolute
266 * is true, then it will sleep until the default timer reaches the
267 * specified number of seconds. If the mode is relative, the thread
268 * will sleep for that many seconds. Unlike system sleep functions,
269 * this one automatically resumes sleep if sleep was interrupted by a
270 * signal. Therefore, calling this function is guaranteed to sleep for
271 * at least the requested amount of time.
272 * \param seconds Number of seconds.
273 * \param mode The timer mode.
275 static void sleep(scalar seconds
, enum mode mode
= relative
);
280 void added_to_runloop(runloop
& runloop
);
281 void detach_from_runloop();
288 timer_source
* source_
;
295 class game_time
: public timer_source
299 game_time(scalar timestep
) :
308 return reference_
+ scalar(ticks_
) * scale_
;
313 reference_
= SCALAR(0.0);
317 void scale(scalar factor
)
319 reference_
= ticks();
321 scale_
= timestep_
* factor
;
325 unsigned step(unsigned step
= 1)
343 #endif // _MOOF_TIMER_HH_
This page took 0.060624 seconds and 4 git commands to generate.