X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Ftimer.cc;h=9b105b4c991fcb73582ff0ad86ca73091ef5c85d;hp=273625640ab4a78dedfda47a691981972a98d7cf;hb=d6990468d297a6cbee98e4d0d33ab37e1b2352c9;hpb=831f04d4bc19a390415ac0bbac4331c7a65509bc diff --git a/src/moof/timer.cc b/src/moof/timer.cc index 2736256..9b105b4 100644 --- a/src/moof/timer.cc +++ b/src/moof/timer.cc @@ -9,41 +9,30 @@ * **************************************************************************/ +#include "config.h" + #include #include #include #include -#include "log.hh" +#include "debug.hh" #include "timer.hh" -#if HAVE_CONFIG_H -#include "config.h" -#endif - namespace moof { -scalar timer::gNextFire = std::numeric_limits::max(); -std::map timer::gTimers; - - -unsigned timer::new_identifier() -{ - static unsigned id = 1; - return id++; -} - - -void timer::init(const function& function, scalar seconds, mode mode) +void timer::init(const function& function, + scalar seconds, + mode mode, + runloop* runloop) { invalidate(); + ASSERT(runloop && "can't schedule timer without a runloop"); - mode_ = mode; - - if (mode_ != invalid) + if ((mode_ = mode) != invalid) { function_ = function; @@ -57,104 +46,39 @@ void timer::init(const function& function, scalar seconds, mode mode) interval_ = seconds; } - id_ = new_identifier(); - gTimers.insert(std::pair(id_, this)); - - if (absolute_ < gNextFire) gNextFire = absolute_; + runloop->add_timer(this); + runloop_ = runloop; } } -bool timer::is_valid() const -{ - return mode_ != invalid; -} - void timer::invalidate() { if (mode_ != invalid) { - gTimers.erase(id_); mode_ = invalid; + absolute_ = SCALAR(0.0); - if (is_equal(absolute_, gNextFire)) gNextFire = find_next_expiration(); + runloop_->remove_timer(this); + runloop_ = 0; } } -void timer::fire() +void timer::fire(scalar t) { - scalar t = ticks(); - if (function_) function_(*this, t); if (is_repeating()) { - scalar absolute = absolute_; - if (is_equal(absolute_, t, 1.0)) absolute_ += interval_; else absolute_ = interval_ + t; - - if (is_equal(absolute, gNextFire)) gNextFire = find_next_expiration(); - } - else - { - invalidate(); - } -} - - -scalar timer::find_next_expiration() -{ - std::map::iterator it; - scalar nextFire = std::numeric_limits::max(); - - for (it = gTimers.begin(); it != gTimers.end(); ++it) - { - scalar absolute = (*it).second->absolute_; - if (absolute < nextFire) nextFire = absolute; - } - - return nextFire; -} - - -scalar timer::seconds_remaining() const -{ - return absolute_ - ticks(); -} - -bool timer::is_expired() const -{ - return seconds_remaining() < 0.0; -} - -bool timer::is_repeating() const -{ - return mode_ == repeat; -} - - -void timer::fire_expired_timers() -{ - fire_expired_timers(ticks()); -} - -void timer::fire_expired_timers(scalar t) -{ - std::map::iterator it; - - if (gNextFire > t) return; - - for (it = gTimers.begin(); it != gTimers.end(); ++it) - { - timer* timer = (*it).second; - if (timer->is_expired()) timer->fire(); } + else invalidate(); } -#if HAVE_CLOCK_GETTIME +#if ENABLE_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 @@ -175,7 +99,7 @@ static time_t set_reference() return ts.tv_sec; } -static const time_t reference = set_reference(); +static const time_t reference_ = set_reference(); scalar timer::ticks() @@ -185,47 +109,44 @@ scalar timer::ticks() 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; + return scalar(ts.tv_sec - reference_) + + scalar(ts.tv_nsec) * SCALAR(0.000000001); } void timer::sleep(scalar seconds, mode mode) { - struct timespec ts; - int ret; - if (mode == absolute) seconds -= ticks(); - ts.tv_sec = time_t(seconds); - ts.tv_nsec = long((seconds - scalar(ts.tv_sec)) * 1000000000.0); + if (seconds < SCALAR(0.0)) return; - do - { - ret = nanosleep(&ts, &ts); - } - while (ret == -1 && errno == EINTR); + struct timespec ts; + ts.tv_sec = seconds; + ts.tv_nsec = (seconds - scalar(ts.tv_sec)) * SCALAR(1000000000.0); + + int ret; + do ret = nanosleep(&ts, &ts); while (ret == -1 && errno == EINTR); } -#else // ! HAVE_CLOCK_GETTIME +#else // ! ENABLE_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. +// a kick in the pants. It could end up being just as good anyway. scalar timer::ticks() { - Uint32 ms = SDL_GetTicks(); - return scalar(ms / 1000) + scalar(ms % 1000) / 1000.0; + return scalar(SDL_GetTicks()) * SCALAR(0.001); } void timer::sleep(scalar seconds, mode mode) { if (mode == absolute) seconds -= ticks(); - SDL_Delay(Uint32(clamp(int(seconds * 1000.0), 0, 1000))); + if (seconds < SCALAR(0.0)) return; + SDL_Delay(seconds * SCALAR(1000.0)); } -#endif // HAVE_CLOCK_GETTIME +#endif // ENABLE_CLOCK_GETTIME } // namespace moof