]>
Dogcows Code - chaz/yoink/blob - src/moof/timer.cc
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 void timer::init(const function
& function
,
33 ASSERT(runloop
&& "can't schedule timer without a runloop");
35 if ((mode_
= mode
) != invalid
)
45 absolute_
= seconds
- ticks();
49 runloop
->add_timer(this);
55 void timer::invalidate()
60 absolute_
= SCALAR(0.0);
62 runloop_
->remove_timer(this);
68 void timer::fire(scalar t
)
70 if (function_
) function_(*this, t
);
74 if (is_equal(absolute_
, t
, 1.0)) absolute_
+= interval_
;
75 else absolute_
= interval_
+ t
;
81 #if ENABLE_CLOCK_GETTIME
83 // Since the monotonic clock will provide us with the time since the
84 // computer started, the number of seconds since that time could easily
85 // become so large that it cannot be accurately stored in a float (even
86 // with as little two days uptime), therefore we need to start from a more
87 // recent reference (when the program starts). Of course this isn't much
88 // of an issue if scalar is a double-precision number.
90 static time_t set_reference()
94 if (clock_gettime(CLOCK_MONOTONIC
, &ts
) != 0)
102 static const time_t reference_
= set_reference();
105 scalar
timer::ticks()
109 int result
= clock_gettime(CLOCK_MONOTONIC
, &ts
);
110 ASSERT(result
== 0 && "cannot access clock");
112 return scalar(ts
.tv_sec
- reference_
) +
113 scalar(ts
.tv_nsec
) * SCALAR(0.000000001);
116 void timer::sleep(scalar seconds
, mode mode
)
118 if (mode
== absolute
) seconds
-= ticks();
119 if (seconds
< SCALAR(0.0)) return;
123 ts
.tv_nsec
= (seconds
- scalar(ts
.tv_sec
)) * SCALAR(1000000000.0);
126 do ret
= nanosleep(&ts
, &ts
); while (ret
== -1 && errno
== EINTR
);
130 #else // ! ENABLE_CLOCK_GETTIME
133 // If we don't have posix timers, we'll have to use a different timing
134 // method. SDL only promises centisecond accuracy, but that's better than
135 // a kick in the pants. It could end up being just as good anyway.
137 scalar
timer::ticks()
139 return scalar(SDL_GetTicks()) * SCALAR(0.001);
142 void timer::sleep(scalar seconds
, mode mode
)
144 if (mode
== absolute
) seconds
-= ticks();
145 if (seconds
< SCALAR(0.0)) return;
146 SDL_Delay(seconds
* SCALAR(1000.0));
149 #endif // ENABLE_CLOCK_GETTIME
This page took 0.039936 seconds and 5 git commands to generate.