1 #include <mbgl/util/timer.hpp>
2
3 #include <mbgl/util/run_loop.hpp>
4
5 #include <uv.h>
6
7 namespace mbgl {
8 namespace util {
9
10 class Timer::Impl {
11 public:
Impl()12 Impl() : timer(new uv_timer_t) {
13 auto* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle());
14 if (uv_timer_init(loop, timer) != 0) {
15 throw std::runtime_error("Failed to initialize timer.");
16 }
17
18 handle()->data = this;
19 uv_unref(handle());
20 }
21
~Impl()22 ~Impl() {
23 uv_close(handle(), [](uv_handle_t* h) {
24 delete reinterpret_cast<uv_timer_t*>(h);
25 });
26 }
27
start(uint64_t timeout,uint64_t repeat,std::function<void ()> && cb_)28 void start(uint64_t timeout, uint64_t repeat, std::function<void ()>&& cb_) {
29 cb = std::move(cb_);
30 if (uv_timer_start(timer, timerCallback, timeout, repeat) != 0) {
31 throw std::runtime_error("Failed to start timer.");
32 }
33 }
34
stop()35 void stop() {
36 cb = nullptr;
37 if (uv_timer_stop(timer) != 0) {
38 throw std::runtime_error("Failed to stop timer.");
39 }
40 }
41
42 private:
timerCallback(uv_timer_t * handle)43 static void timerCallback(uv_timer_t* handle) {
44 reinterpret_cast<Impl*>(handle->data)->cb();
45 }
46
handle()47 uv_handle_t* handle() {
48 return reinterpret_cast<uv_handle_t*>(timer);
49 }
50
51 uv_timer_t* timer;
52
53 std::function<void()> cb;
54 };
55
Timer()56 Timer::Timer()
57 : impl(std::make_unique<Impl>()) {
58 }
59
60 Timer::~Timer() = default;
61
start(Duration timeout,Duration repeat,std::function<void ()> && cb)62 void Timer::start(Duration timeout, Duration repeat, std::function<void()>&& cb) {
63 impl->start(std::chrono::duration_cast<Milliseconds>(timeout).count(),
64 std::chrono::duration_cast<Milliseconds>(repeat).count(),
65 std::move(cb));
66 }
67
stop()68 void Timer::stop() {
69 impl->stop();
70 }
71
72 } // namespace util
73 } // namespace mbgl
74