diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-09-17 15:29:24 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-09-24 16:14:10 +0200 |
commit | ba18c08524cffd3fa03adf49f680f3a80390d61d (patch) | |
tree | a97cbbc9a83bc2ad72c63259eaee78572526bfc6 | |
parent | 89cd310cf6117586701b1e72fe7c2bf0fbd760db (diff) | |
download | qtlocation-mapboxgl-ba18c08524cffd3fa03adf49f680f3a80390d61d.tar.gz |
add a callback to stop() to allow running the current thread's event loop
-rw-r--r-- | common/glfw_view.cpp | 6 | ||||
-rw-r--r-- | common/glfw_view.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/map/map.hpp | 7 | ||||
-rw-r--r-- | include/mbgl/map/view.hpp | 2 | ||||
-rw-r--r-- | src/map/map.cpp | 13 |
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; |