X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FTimer.cc;fp=src%2FMoof%2FTimer.cc;h=0000000000000000000000000000000000000000;hp=3e42818962d5df7e124f7edc96ed4384ca3dc171;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/Moof/Timer.cc b/src/Moof/Timer.cc deleted file mode 100644 index 3e42818..0000000 --- a/src/Moof/Timer.cc +++ /dev/null @@ -1,232 +0,0 @@ - -/*] Copyright (c) 2009-2010, Charles McGarvey [************************** -**] All rights reserved. -* -* vi:ts=4 sw=4 tw=75 -* -* Distributable under the terms and conditions of the 2-clause BSD license; -* see the file COPYING for a complete text of the license. -* -**************************************************************************/ - -#include -#include -#include - -#include - -#include "Log.hh" -#include "Timer.hh" - -#if HAVE_CONFIG_H -#include "config.h" -#endif - - -namespace Mf { - - -Scalar Timer::gNextFire = std::numeric_limits::max(); -std::map Timer::gTimers; - - -unsigned Timer::getNewID() -{ - static unsigned id = 1; - return id++; -} - - -void Timer::init(const Function& function, Scalar seconds, Mode mode) -{ - invalidate(); - - mMode = mode; - - if (mMode != INVALID) - { - mFunction = function; - - if (mode == ACTUAL) - { - mAbsolute = seconds; - } - else - { - mAbsolute = seconds - getTicks(); - mInterval = seconds; - } - - mId = getNewID(); - gTimers.insert(std::pair(mId, this)); - - if (mAbsolute < gNextFire) gNextFire = mAbsolute; - } -} - - -bool Timer::isValid() const -{ - return mMode != INVALID; -} - -void Timer::invalidate() -{ - if (mMode != INVALID) - { - gTimers.erase(mId); - mMode = INVALID; - - if (isEqual(mAbsolute, gNextFire)) gNextFire = findNextFire(); - } -} - - -void Timer::fire() -{ - Scalar t = getTicks(); - - if (mFunction) mFunction(*this, t); - - if (isRepeating()) - { - Scalar absolute = mAbsolute; - - if (isEqual(mAbsolute, t, 1.0)) mAbsolute += mInterval; - else mAbsolute = mInterval + t; - - if (isEqual(absolute, gNextFire)) gNextFire = findNextFire(); - } - else - { - invalidate(); - } -} - - -Scalar Timer::findNextFire() -{ - std::map::iterator it; - Scalar nextFire = std::numeric_limits::max(); - - for (it = gTimers.begin(); it != gTimers.end(); ++it) - { - Scalar absolute = (*it).second->mAbsolute; - if (absolute < nextFire) nextFire = absolute; - } - - return nextFire; -} - - -Scalar Timer::getSecondsRemaining() const -{ - return mAbsolute - getTicks(); -} - -bool Timer::isExpired() const -{ - return getSecondsRemaining() < 0.0; -} - -bool Timer::isRepeating() const -{ - return mMode == REPEAT; -} - - -void Timer::fireIfExpired() -{ - fireIfExpired(getTicks()); -} - -void Timer::fireIfExpired(Scalar t) -{ - std::map::iterator it; - - if (gNextFire > t) return; - - for (it = gTimers.begin(); it != gTimers.end(); ++it) - { - Timer* timer = (*it).second; - if (timer->isExpired()) timer->fire(); - } -} - - -#if HAVE_CLOCK_GETTIME - -// Since the monotonic clock will provide us with the time since the -// computer started, the number of seconds since that time could easily -// become so large that it cannot be accurately stored in a float (even -// with as little two days uptime), therefore we need to start from a more -// recent reference (when the program starts). Of course this isn't much -// of an issue if scalar is a double-precision number. - -static time_t setReference_() -{ - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) - { - return 0; - } - - return ts.tv_sec; -} - -static const time_t reference = setReference_(); - - -Scalar Timer::getTicks() -{ - struct timespec ts; - - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - ASSERT(result == 0 && "cannot access clock"); - - return Scalar(ts.tv_sec - reference) + - Scalar(ts.tv_nsec) / 1000000000.0; -} - -void Timer::sleep(Scalar seconds, Mode mode) -{ - struct timespec ts; - int ret; - - if (mode == ACTUAL) seconds -= getTicks(); - ts.tv_sec = time_t(seconds); - ts.tv_nsec = long((seconds - Scalar(ts.tv_sec)) * 1000000000.0); - - do - { - ret = nanosleep(&ts, &ts); - } - while (ret == -1 && errno == EINTR); -} - - -#else // ! HAVE_CLOCK_GETTIME - - -// If we don't have posix timers, we'll have to use a different timing -// method. SDL only promises centisecond accuracy, but that's better than -// a kick in the pants. - -Scalar Timer::getTicks() -{ - Uint32 ms = SDL_GetTicks(); - return Scalar(ms / 1000) + Scalar(ms % 1000) / 1000.0; -} - -void Timer::sleep(Scalar seconds, Mode mode) -{ - if (mode == ACTUAL) seconds -= getTicks(); - SDL_Delay(Uint32(cml::clamp(int(seconds * 1000.0), 0, 1000))); -} - -#endif // HAVE_CLOCK_GETTIME - - -} // namespace Mf -