diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-04-22 16:54:55 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-04-22 16:54:55 +0200 |
commit | 1ecff578295a44cd33e476acf9960d989e65b99b (patch) | |
tree | 820b2769560b0460d188482dbd660639cacefd2f /common | |
parent | 9ff9d0edb55bcf15eb030b96f57cc6d5c63b8c5c (diff) | |
download | qtlocation-mapboxgl-1ecff578295a44cd33e476acf9960d989e65b99b.tar.gz |
use libuv event loop in the glfw view
Integrates libuv's default loop with GLFW's glfwWaitEvents() call. See https://github.com/joyent/libuv/issues/1246 for more details on integrating event loops.
fixes #149
Diffstat (limited to 'common')
-rw-r--r-- | common/curl_request.cpp | 2 | ||||
-rw-r--r-- | common/glfw_view.cpp | 102 | ||||
-rw-r--r-- | common/glfw_view.hpp | 7 |
3 files changed, 99 insertions, 12 deletions
diff --git a/common/curl_request.cpp b/common/curl_request.cpp index dc9db0269c..7cfe8fcabd 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -341,6 +341,8 @@ void async_cancel_cb(uv_async_t * /*async*/) { } void thread_init_cb() { + curl_global_init(CURL_GLOBAL_ALL); + loop = uv_loop_new(); uv_async_init(loop, &async_add, async_add_cb); uv_async_init(loop, &async_cancel, async_cancel_cb); diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp index c4fafb69ac..82e9aad745 100644 --- a/common/glfw_view.cpp +++ b/common/glfw_view.cpp @@ -1,7 +1,40 @@ #include "glfw_view.hpp" + +#ifndef HAVE_KQUEUE +# if defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# define HAVE_KQUEUE 1 +# endif +#endif + +#ifndef HAVE_EPOLL +# if defined(__linux__) +# define HAVE_EPOLL 1 +# endif +#endif + +#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) + +#if defined(HAVE_KQUEUE) +# include <sys/types.h> +# include <sys/event.h> +# include <sys/time.h> +#endif + +#if defined(HAVE_EPOLL) +# include <sys/epoll.h> +#endif + +#endif + + MapView::MapView(llmr::Settings &settings, bool fullscreen) - : fullscreen(fullscreen), settings(settings), map(settings) {} + : fullscreen(fullscreen), settings(settings), map(settings), + stop_event_listener(false) {} MapView::~MapView() { glfwTerminate(); } @@ -163,28 +196,70 @@ void MapView::mousemove(GLFWwindow *window, double x, double y) { mapView->last_y = y; } +void MapView::eventloop(void *arg) { + MapView *view = static_cast<MapView *>(arg); + int r = 0; + int fd = 0; + int timeout; + + while (!view->stop_event_listener) { + fd = uv_backend_fd(uv_default_loop()); + timeout = uv_backend_timeout(uv_default_loop()); + + do { +#if defined(HAVE_KQUEUE) + struct timespec ts; + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + r = kevent(fd, NULL, 0, NULL, 0, &ts); +#elif defined(HAVE_EPOLL) + { + struct epoll_event ev; + r = epoll_wait(fd, &ev, 1, timeout); + } +#endif + } while (r == -1 && errno == EINTR); + glfwPostEmptyEvent(); + uv_sem_wait(&view->event_listener); + } +} + int MapView::run() { + uv_thread_t embed_thread; + + uv_run(uv_default_loop(), UV_RUN_NOWAIT); + + /* Start worker that will interrupt external loop */ + stop_event_listener = false; + uv_sem_init(&event_listener, 0); + uv_thread_create(&embed_thread, eventloop, this); + while (!glfwWindowShouldClose(window)) { - llmr::platform::cleanup(); - if (dirty) { - try { - dirty = map.render(); - } - catch (std::exception &ex) { - fprintf(stderr, "exception: %s\n", ex.what()); - } - glfwSwapBuffers(window); - fps(); + bool dirty = false; + try { + dirty = map.render(); } + catch (std::exception &ex) { + fprintf(stderr, "exception: %s\n", ex.what()); + } + glfwSwapBuffers(window); + fps(); if (dirty) { glfwPollEvents(); } else { glfwWaitEvents(); } + + uv_run(uv_default_loop(), UV_RUN_NOWAIT); + uv_sem_post(&event_listener); } + stop_event_listener = true; + + uv_thread_join(&embed_thread); + return 0; } @@ -234,5 +309,10 @@ void show_debug_image(std::string name, const char *data, size_t width, size_t h glfwMakeContextCurrent(current_window); } + +void restart() { + glfwPostEmptyEvent(); +} + } } diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp index d72debb11d..8647c8ad67 100644 --- a/common/glfw_view.hpp +++ b/common/glfw_view.hpp @@ -3,6 +3,7 @@ #include <llmr/llmr.hpp> #include <GLFW/glfw3.h> +#include <uv.h> class MapView { public: @@ -17,13 +18,14 @@ public: static void mouseclick(GLFWwindow *window, int button, int action, int modifiers); static void mousemove(GLFWwindow *window, double x, double y); + static void eventloop(void *arg); + int run(); void fps(); public: bool fullscreen = false; - bool dirty = true; double last_x = 0, last_y = 0; bool tracking = false; @@ -34,6 +36,9 @@ public: GLFWwindow *window = nullptr; llmr::Settings &settings; llmr::Map map; + + uv_sem_t event_listener; + std::atomic<bool> stop_event_listener; }; #endif |