summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <tmpsantos@gmail.com>2017-07-27 13:34:04 +0300
committerThiago Marcos P. Santos <tmpsantos@gmail.com>2017-07-27 14:00:58 +0300
commita74e5b0d43a844be9844dd605f704634bc6114a0 (patch)
treeb6e3d0a9dd6d76e364d446a1af53b9b5b6dec3bb
parent48481db47b82a548904b0c269e70e5321ab11503 (diff)
downloadqtlocation-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.cmake2
-rw-r--r--src/mbgl/util/alarm.cpp58
-rw-r--r--src/mbgl/util/alarm.hpp40
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