]>
Dogcows Code - chaz/yoink/blob - timer.cc
f16a962dfa688b032ad92da9506a92c6b24ab416
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 **************************************************************************/
27 scalar
timer::next_event_
= std::numeric_limits
<scalar
>::max();
28 hash
<unsigned,timer
*,hash_function
> timer::timers_
;
31 unsigned timer::new_identifier()
33 static unsigned id
= 1;
38 void timer::init(const function
& function
, scalar seconds
, mode mode
)
54 absolute_
= seconds
- ticks();
58 id_
= new_identifier();
59 timers_
.insert(std::pair
<unsigned,timer
*>(id_
, this));
61 if (absolute_
< next_event_
) next_event_
= absolute_
;
66 bool timer::is_valid() const
68 return mode_
!= invalid
;
71 void timer::invalidate()
78 if (is_equal(absolute_
, next_event_
))
80 next_event_
= find_next_event();
90 if (function_
) function_(*this, t
);
94 scalar absolute
= absolute_
;
96 if (is_equal(absolute_
, t
, 1.0)) absolute_
+= interval_
;
97 else absolute_
= interval_
+ t
;
99 if (is_equal(absolute
, next_event_
))
101 next_event_
= find_next_event();
111 scalar
timer::find_next_event()
113 scalar next_fire
= std::numeric_limits
<scalar
>::max();
115 hash
<unsigned,timer
*,hash_function
>::iterator it
;
116 for (it
= timers_
.begin(); it
.valid(); ++it
)
118 scalar absolute
= (*it
).second
->absolute_
;
119 if (absolute
< next_fire
) next_fire
= absolute
;
126 scalar
timer::seconds_remaining() const
128 return absolute_
- ticks();
131 scalar
timer::next_expiration() const
136 bool timer::is_expired() const
138 return seconds_remaining() < 0.0;
141 bool timer::is_repeating() const
143 return mode_
== repeat
;
147 void timer::fire_expired_timers(scalar t
)
149 if (t
< next_event_
) return;
151 hash
<unsigned,timer
*,hash_function
>::iterator it
;
152 for (it
= timers_
.begin(); it
.valid(); ++it
)
154 timer
* timer
= (*it
).second
;
155 if (timer
->is_expired()) timer
->fire();
162 #if USE_CLOCK_GETTIME
164 // Since the monotonic clock will provide us with the time since the
165 // computer started, the number of seconds since that time could easily
166 // become so large that it cannot be accurately stored in a float (even
167 // with as little two days uptime), therefore we need to start from a more
168 // recent reference (when the program starts). Of course this isn't much
169 // of an issue if scalar is a double-precision number.
171 static time_t set_reference()
175 if (clock_gettime(CLOCK_MONOTONIC
, &ts
) != 0)
183 static const time_t reference_
= set_reference();
186 scalar
timer::ticks()
190 int result
= clock_gettime(CLOCK_MONOTONIC
, &ts
);
191 ASSERT(result
== 0 && "cannot access clock");
193 return scalar(ts
.tv_sec
- reference_
) +
194 scalar(ts
.tv_nsec
) * SCALAR(0.000000001);
197 void timer::sleep(scalar seconds
, mode mode
)
199 if (mode
== absolute
) seconds
-= ticks();
200 if (seconds
< SCALAR(0.0)) return;
204 ts
.tv_nsec
= (seconds
- scalar(ts
.tv_sec
)) * SCALAR(1000000000.0);
207 do ret
= nanosleep(&ts
, &ts
); while (ret
== -1 && errno
== EINTR
);
211 #else // ! USE_CLOCK_GETTIME
214 // If we don't have posix timers, we'll have to use a different timing
215 // method. SDL only promises centisecond accuracy, but that's better than
216 // a kick in the pants. It could end up being just as good anyway.
218 scalar
timer::ticks()
220 return scalar(SDL_GetTicks()) * SCALAR(0.001);
223 void timer::sleep(scalar seconds
, mode mode
)
225 if (mode
== absolute
) seconds
-= ticks();
226 if (seconds
< SCALAR(0.0)) return;
227 SDL_Delay(seconds
* SCALAR(1000.0));
230 #endif // USE_CLOCK_GETTIME
This page took 0.050231 seconds and 3 git commands to generate.