summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-04-22 16:54:55 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-04-22 16:54:55 +0200
commit1ecff578295a44cd33e476acf9960d989e65b99b (patch)
tree820b2769560b0460d188482dbd660639cacefd2f /common
parent9ff9d0edb55bcf15eb030b96f57cc6d5c63b8c5c (diff)
downloadqtlocation-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.cpp2
-rw-r--r--common/glfw_view.cpp102
-rw-r--r--common/glfw_view.hpp7
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