summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-09-17 15:29:24 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-09-24 16:14:10 +0200
commitba18c08524cffd3fa03adf49f680f3a80390d61d (patch)
treea97cbbc9a83bc2ad72c63259eaee78572526bfc6
parent89cd310cf6117586701b1e72fe7c2bf0fbd760db (diff)
downloadqtlocation-mapboxgl-ba18c08524cffd3fa03adf49f680f3a80390d61d.tar.gz
add a callback to stop() to allow running the current thread's event loop
-rw-r--r--common/glfw_view.cpp6
-rw-r--r--common/glfw_view.hpp1
-rw-r--r--include/mbgl/map/map.hpp7
-rw-r--r--include/mbgl/map/view.hpp2
-rw-r--r--src/map/map.cpp13
5 files changed, 26 insertions, 3 deletions
diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp
index f53090a000..fb54d55f39 100644
--- a/common/glfw_view.cpp
+++ b/common/glfw_view.cpp
@@ -183,7 +183,7 @@ int GLFWView::run() {
glfwWaitEvents();
}
- map->stop();
+ map->stop(glfwWaitEvents);
return 0;
}
@@ -192,6 +192,10 @@ void GLFWView::make_active() {
glfwMakeContextCurrent(window);
}
+void GLFWView::notify() {
+ glfwPostEmptyEvent();
+}
+
void GLFWView::swap() {
glfwPostEmptyEvent();
diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp
index d2f6872fc7..481b1598bb 100644
--- a/common/glfw_view.hpp
+++ b/common/glfw_view.hpp
@@ -17,6 +17,7 @@ public:
void initialize(mbgl::Map *map);
void swap();
void make_active();
+ void notify();
void notify_map_change(mbgl::MapChange change, mbgl::timestamp delay = 0);
static void key(GLFWwindow *window, int key, int scancode, int action, int mods);
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index c389d898b1..48c4e89cc9 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -31,6 +31,8 @@ class FileSource;
class View;
class Map : private util::noncopyable {
+ typedef void (*stop_callback)();
+
public:
explicit Map(View &view);
~Map();
@@ -38,7 +40,7 @@ public:
// Start/stop the map render thread. the start() call is asynchronous, while the stop() call
// will block until the map rendering thread stopped.
void start();
- void stop();
+ void stop(stop_callback cb = nullptr);
// Runs the map event loop. ONLY run this function when you want to get render a single frame
// with this map object. It will *not* spawn a separate thread and instead block until the
@@ -179,6 +181,9 @@ private:
// ready for rendering.
std::atomic_flag is_rendered = ATOMIC_FLAG_INIT;
+ // Stores whether the map thread has been stopped already.
+ std::atomic_bool is_stopped;
+
public:
View &view;
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
index 92d60d4d02..bbdcd97c79 100644
--- a/include/mbgl/map/view.hpp
+++ b/include/mbgl/map/view.hpp
@@ -41,6 +41,8 @@ public:
return 0;
}
+ virtual void notify() = 0;
+
// Notifies a watcher of map x/y/scale/rotation changes.
// Must only be called from the same thread that caused the change.
// Must not be called from the render thread.
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 93e1bea536..b1a7b1c2fd 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -75,6 +75,9 @@ void Map::start() {
// updated rendering. Only in these cases, we attach the async handlers.
async = true;
+ // Reset the flag.
+ is_stopped = false;
+
// Setup async notifications
uv_async_init(**loop, async_terminate.get(), terminate);
async_terminate->data = this;
@@ -97,15 +100,23 @@ void Map::start() {
#ifndef NDEBUG
map->map_thread = -1;
#endif
+ map->is_stopped = true;
}, this);
}
-void Map::stop() {
+void Map::stop(stop_callback cb) {
assert(uv_thread_self() == main_thread);
assert(main_thread != map_thread);
+ assert(async);
uv_async_send(async_terminate.get());
+ if (cb) {
+ while (!is_stopped) {
+ cb();
+ }
+ }
+
uv_thread_join(*thread);
async = false;