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