diff options
author | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2017-07-27 13:34:04 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2017-07-27 14:00:58 +0300 |
commit | a74e5b0d43a844be9844dd605f704634bc6114a0 (patch) | |
tree | b6e3d0a9dd6d76e364d446a1af53b9b5b6dec3bb | |
parent | 48481db47b82a548904b0c269e70e5321ab11503 (diff) | |
download | qtlocation-mapboxgl-a74e5b0d43a844be9844dd605f704634bc6114a0.tar.gz |
[core] Introduce the util::Alarm
A variation of util::Timer that does not require owning thread
to sleep in a select().
-rw-r--r-- | cmake/core-files.cmake | 2 | ||||
-rw-r--r-- | src/mbgl/util/alarm.cpp | 58 | ||||
-rw-r--r-- | src/mbgl/util/alarm.hpp | 40 |
3 files changed, 100 insertions, 0 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 1bbe739256..0d27c81aee 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -563,6 +563,8 @@ set(MBGL_CORE_FILES include/mbgl/util/work_request.hpp include/mbgl/util/work_task.hpp include/mbgl/util/work_task_impl.hpp + src/mbgl/util/alarm.cpp + src/mbgl/util/alarm.hpp src/mbgl/util/chrono.cpp src/mbgl/util/clip_id.cpp src/mbgl/util/clip_id.hpp diff --git a/src/mbgl/util/alarm.cpp b/src/mbgl/util/alarm.cpp new file mode 100644 index 0000000000..1d20321db9 --- /dev/null +++ b/src/mbgl/util/alarm.cpp @@ -0,0 +1,58 @@ +#include <mbgl/util/alarm.hpp> + +#include <mbgl/actor/actor_ref.hpp> +#include <mbgl/actor/mailbox.hpp> +#include <mbgl/util/run_loop.hpp> +#include <mbgl/util/timer.hpp> + +#include <cassert> + +namespace mbgl { +namespace util { + +class Alarm::Impl { +public: + Impl(ActorRef<Alarm::Impl>, ActorRef<Alarm> parent_) : parent(parent_) {} + + void start(Duration timeout) { + alarm.start(timeout, mbgl::Duration::zero(), [this]() { + parent.invoke(&Alarm::fired); + }); + } + + void stop() { + alarm.stop(); + } + +private: + Timer alarm; + ActorRef<Alarm> parent; +}; + +Alarm::Alarm() + // FIXME: Replace with util::Scheduler::Get() + : mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())) + , impl("Alarm", ActorRef<Alarm>(*this, mailbox)) { +} + +Alarm::~Alarm() { + mailbox->close(); +} + +void Alarm::start(Duration timeout, std::function<void()>&& cb) { + assert(cb); + callback = std::move(cb); + + impl.actor().invoke(&Impl::start, timeout); +} + +void Alarm::stop() { + impl.actor().invoke(&Impl::stop); +} + +void Alarm::fired() { + callback(); +} + +} // namespace util +} // namespace mbgl diff --git a/src/mbgl/util/alarm.hpp b/src/mbgl/util/alarm.hpp new file mode 100644 index 0000000000..81e92d74c7 --- /dev/null +++ b/src/mbgl/util/alarm.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include <mbgl/util/chrono.hpp> +#include <mbgl/util/noncopyable.hpp> +#include <mbgl/util/thread.hpp> + +#include <functional> +#include <memory> + +namespace mbgl { + +class Mailbox; + +namespace util { + +// Alarm works similarly to the util::Timer class, with the +// difference it does not require the owning thread to sleep +// in a select(). It is useful for platforms like Android +// where you cannot set a timer on the main thread because the +// NDK does not have a concept of timeout callback in the ALooper. +class Alarm : private util::noncopyable { +public: + Alarm(); + ~Alarm(); + + void start(Duration timeout, std::function<void()>&&); + void stop(); + +private: + class Impl; + + void fired(); + + std::shared_ptr<Mailbox> mailbox; + util::Thread<Impl> impl; + std::function<void()> callback; +}; + +} // namespace util +} // namespace mbgl |