add a callback to stop() to allow running the current thread's event loop
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user