]>
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 **************************************************************************/
29 Scalar
Timer::gNextFire
= std::numeric_limits
<Scalar
>::max();
30 std::map
<unsigned,Timer
*> Timer::gTimers
;
33 unsigned Timer::getNewID()
35 static unsigned id
= 1;
40 void Timer::init(const Function
& function
, Scalar seconds
, Mode mode
)
56 mAbsolute
= seconds
- getTicks();
61 gTimers
.insert(std::pair
<unsigned,Timer
*>(mId
, this));
63 if (mAbsolute
< gNextFire
) gNextFire
= mAbsolute
;
68 bool Timer::isValid() const
70 return mMode
!= INVALID
;
73 void Timer::invalidate()
80 if (isEqual(mAbsolute
, gNextFire
)) gNextFire
= findNextFire();
87 Scalar t
= getTicks();
89 if (mFunction
) mFunction(*this, t
);
93 Scalar absolute
= mAbsolute
;
95 if (isEqual(mAbsolute
, t
, 1.0)) mAbsolute
+= mInterval
;
96 else mAbsolute
= mInterval
+ t
;
98 if (isEqual(absolute
, gNextFire
)) gNextFire
= findNextFire();
107 Scalar
Timer::findNextFire()
109 std::map
<unsigned,Timer
*>::iterator it
;
110 Scalar nextFire
= std::numeric_limits
<Scalar
>::max();
112 for (it
= gTimers
.begin(); it
!= gTimers
.end(); ++it
)
114 Scalar absolute
= (*it
).second
->mAbsolute
;
115 if (absolute
< nextFire
) nextFire
= absolute
;
122 Scalar
Timer::getSecondsRemaining() const
124 return mAbsolute
- getTicks();
127 bool Timer::isExpired() const
129 return getSecondsRemaining() < 0.0;
132 bool Timer::isRepeating() const
134 return mMode
== REPEAT
;
138 void Timer::fireIfExpired()
140 fireIfExpired(getTicks());
143 void Timer::fireIfExpired(Scalar t
)
145 std::map
<unsigned,Timer
*>::iterator it
;
147 if (gNextFire
> t
) return;
149 for (it
= gTimers
.begin(); it
!= gTimers
.end(); ++it
)
151 Timer
* timer
= (*it
).second
;
152 if (timer
->isExpired()) timer
->fire();
157 #if HAVE_CLOCK_GETTIME
159 // Since the monotonic clock will provide us with the time since the
160 // computer started, the number of seconds since that time could easily
161 // become so large that it cannot be accurately stored in a float (even
162 // with as little two days uptime), therefore we need to start from a more
163 // recent reference (when the program starts). Of course this isn't much
164 // of an issue if scalar is a double-precision number.
166 static time_t setReference_()
170 if (clock_gettime(CLOCK_MONOTONIC
, &ts
) != 0)
178 static const time_t reference
= setReference_();
181 Scalar
Timer::getTicks()
185 int result
= clock_gettime(CLOCK_MONOTONIC
, &ts
);
186 ASSERT(result
== 0 && "cannot access clock");
188 return Scalar(ts
.tv_sec
- reference
) +
189 Scalar(ts
.tv_nsec
) / 1000000000.0;
192 void Timer::sleep(Scalar seconds
, Mode mode
)
197 if (mode
== ACTUAL
) seconds
-= getTicks();
198 ts
.tv_sec
= time_t(seconds
);
199 ts
.tv_nsec
= long((seconds
- Scalar(ts
.tv_sec
)) * 1000000000.0);
203 ret
= nanosleep(&ts
, &ts
);
205 while (ret
== -1 && errno
== EINTR
);
209 #else // ! HAVE_CLOCK_GETTIME
212 // If we don't have posix timers, we'll have to use a different timing
213 // method. SDL only promises centisecond accuracy, but that's better than
214 // a kick in the pants.
216 Scalar
Timer::getTicks()
218 Uint32 ms
= SDL_GetTicks();
219 return Scalar(ms
/ 1000) + Scalar(ms
% 1000) / 1000.0;
222 void Timer::sleep(Scalar seconds
, Mode mode
)
224 if (mode
== ACTUAL
) seconds
-= getTicks();
225 SDL_Delay(Uint32(cml::clamp(int(seconds
* 1000.0), 0, 1000)));
228 #endif // HAVE_CLOCK_GETTIME
This page took 0.041449 seconds and 4 git commands to generate.