summaryrefslogtreecommitdiff
path: root/src/common/timer.cpp
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-03-15 19:34:59 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-03-16 18:58:48 -0700
commitc812c92d1a1835f0bda783e709481188c8d92225 (patch)
treeb401ede48a088ad1aaed88fe3b997cd26ff7ae08 /src/common/timer.cpp
parentde9ee1b9754af9d954487121947352f32d7ebb7e (diff)
downloadtmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.gz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.bz2
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.xz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.zip
Clean up header organization
Diffstat (limited to 'src/common/timer.cpp')
-rw-r--r--src/common/timer.cpp201
1 files changed, 0 insertions, 201 deletions
diff --git a/src/common/timer.cpp b/src/common/timer.cpp
deleted file mode 100644
index b5a2a5e..0000000
--- a/src/common/timer.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include "timer.hpp"
-
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <cassert>
-#include <cstring>
-
-#include <queue>
-
-#include "../strings/zstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-
-#include "utils.hpp"
-
-#include "../poison.hpp"
-
-struct TimerData
-{
- /// This will be reset on call, to avoid problems.
- Timer *owner;
-
- /// When it will be triggered
- tick_t tick;
- /// What will be done
- timer_func func;
- /// Repeat rate - 0 for oneshot
- interval_t interval;
-
- TimerData(Timer *o, tick_t t, timer_func f, interval_t i)
- : owner(o)
- , tick(t)
- , func(std::move(f))
- , interval(i)
- {}
-};
-
-struct TimerCompare
-{
- /// implement "less than"
- bool operator() (dumb_ptr<TimerData> l, dumb_ptr<TimerData> r)
- {
- // C++ provides a max-heap, but we want
- // the smallest tick to be the head (a min-heap).
- return l->tick > r->tick;
- }
-};
-
-static
-std::priority_queue<dumb_ptr<TimerData>, std::vector<dumb_ptr<TimerData>>, TimerCompare> timer_heap;
-
-
-tick_t gettick_cache;
-
-tick_t milli_clock::now(void) noexcept
-{
- struct timeval tval;
- // BUG: This will cause strange behavior if the system clock is changed!
- // it should be reimplemented in terms of clock_gettime(CLOCK_MONOTONIC, )
- gettimeofday(&tval, NULL);
- return gettick_cache = tick_t(std::chrono::seconds(tval.tv_sec)
- + std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::microseconds(tval.tv_usec)));
-}
-
-static
-void do_nothing(TimerData *, tick_t)
-{
-}
-
-void Timer::cancel()
-{
- if (!td)
- return;
-
- assert (this == td->owner);
- td->owner = nullptr;
- td->func = do_nothing;
- td->interval = interval_t::zero();
- td = nullptr;
-}
-
-void Timer::detach()
-{
- assert (this == td->owner);
- td->owner = nullptr;
- td = nullptr;
-}
-
-static
-void push_timer_heap(dumb_ptr<TimerData> td)
-{
- timer_heap.push(td);
-}
-
-static
-dumb_ptr<TimerData> top_timer_heap(void)
-{
- if (timer_heap.empty())
- return dumb_ptr<TimerData>();
- return timer_heap.top();
-}
-
-static
-void pop_timer_heap(void)
-{
- timer_heap.pop();
-}
-
-Timer::Timer(tick_t tick, timer_func func, interval_t interval)
-: td(dumb_ptr<TimerData>::make(this, tick, std::move(func), interval))
-{
- assert (interval >= interval_t::zero());
-
- push_timer_heap(td);
-}
-
-Timer::Timer(Timer&& t)
-: td(t.td)
-{
- t.td = nullptr;
- if (td)
- {
- assert (td->owner == &t);
- td->owner = this;
- }
-}
-
-Timer& Timer::operator = (Timer&& t)
-{
- std::swap(td, t.td);
- if (td)
- {
- assert (td->owner == &t);
- td->owner = this;
- }
- if (t.td)
- {
- assert (t.td->owner == this);
- t.td->owner = &t;
- }
- return *this;
-}
-
-interval_t do_timer(tick_t tick)
-{
- /// Number of milliseconds until it calls this again
- // this says to wait 1 sec if all timers get popped
- interval_t nextmin = std::chrono::seconds(1);
-
- while (dumb_ptr<TimerData> td = top_timer_heap())
- {
- // while the heap is not empty and
- if (td->tick > tick)
- {
- /// Return the time until the next timer needs to goes off
- nextmin = td->tick - tick;
- break;
- }
- pop_timer_heap();
-
- // Prevent destroying the object we're in.
- // Note: this would be surprising in an interval timer,
- // but all interval timers do an immediate explicit detach().
- if (td->owner)
- td->owner->detach();
- // If we are too far past the requested tick, call with
- // the current tick instead to fix reregistration problems
- if (td->tick + std::chrono::seconds(1) < tick)
- td->func(td.operator->(), tick);
- else
- td->func(td.operator->(), td->tick);
-
- if (td->interval == interval_t::zero())
- {
- td.delete_();
- continue;
- }
- if (td->tick + std::chrono::seconds(1) < tick)
- td->tick = tick + td->interval;
- else
- td->tick += td->interval;
- push_timer_heap(td);
- }
-
- return std::max(nextmin, std::chrono::milliseconds(10));
-}
-
-tick_t file_modified(ZString name)
-{
- struct stat buf;
- if (stat(name.c_str(), &buf))
- return tick_t();
- return tick_t(std::chrono::seconds(buf.st_mtime));
-}
-
-bool has_timers()
-{
- return !timer_heap.empty();
-}