diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/llmr-app.gyp | 56 | ||||
-rw-r--r-- | linux/main.cpp | 98 |
2 files changed, 113 insertions, 41 deletions
diff --git a/linux/llmr-app.gyp b/linux/llmr-app.gyp index 06d7ed822e..79c1d4560d 100644 --- a/linux/llmr-app.gyp +++ b/linux/llmr-app.gyp @@ -13,16 +13,52 @@ "./settings.cpp", "./settings.hpp" ], - 'product_extension': 'app', - 'link_settings': { - 'libraries': [ - '<@(glfw3_libraries)', - '-lcurl' - ], - }, - 'cflags': [ - '<@(png_cflags)', - '<@(glfw3_cflags)' + 'conditions': [ + ['OS == "mac"', { + 'product_extension': 'app', + 'mac_bundle_resources': [ + 'Icon.icns', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework', + '$(SDKROOT)/System/Library/Frameworks/IOKit.framework', + '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', + '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework', + ], + }, + 'xcode_settings': { + 'ARCHS': [ "x86_64" ], + 'SDKROOT': 'macosx', + 'SUPPORTED_PLATFORMS':'macosx', + 'OTHER_CPLUSPLUSFLAGS':[ + '<@(glfw3_cflags)' + ], + 'OTHER_LDFLAGS': [ + '-stdlib=libc++', + '<@(glfw3_libraries)', + '-lcurl', + ], + 'SDKROOT': 'macosx', + 'INFOPLIST_FILE': 'Info.plist', + 'CLANG_CXX_LIBRARY': 'libc++', + 'CLANG_CXX_LANGUAGE_STANDARD':'c++11', + 'MACOSX_DEPLOYMENT_TARGET':'10.9', + 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0', + 'CLANG_ENABLE_OBJC_ARC': 'YES' + }, + }, { + 'link_settings': { + 'libraries': [ + '<@(glfw3_libraries)', + '-lcurl' + ], + }, + 'cflags': [ + '<@(png_cflags)', + '<@(glfw3_cflags)' + ], + }] ], "dependencies": [ "../llmr.gyp:llmr-x86" diff --git a/linux/main.cpp b/linux/main.cpp index 1e6c409a0f..328027414e 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -5,15 +5,28 @@ #include "settings.hpp" #include <future> #include <list> +#include <forward_list> #include <chrono> -#include <thread> +#include <pthread.h> + +namespace llmr { +namespace platform { + +struct Request { + pthread_t thread; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + std::string url; + bool done = false; + std::function<void(Response&)> background_function; + std::function<void()> foreground_callback; +}; + +} +} + +std::forward_list<llmr::platform::Request *> requests; -std::list<std::future<void>> futures; -std::list<std::future<void>>::iterator f_it; -std::list<std::function<void()>> callbacks; -std::list<std::function<void()>>::iterator c_it; -std::chrono::milliseconds zero (0); class MapView { public: @@ -159,21 +172,22 @@ public: int run() { while (!glfwWindowShouldClose(window)) { - - f_it = futures.begin(); - c_it = callbacks.begin(); - - while (f_it != futures.end()) { - if (f_it->wait_for(zero) == std::future_status::ready) { - std::function<void()> cb = *c_it; - futures.erase(f_it++); - callbacks.erase(c_it++); - cb(); + bool& dirty = this->dirty; + requests.remove_if([&dirty](llmr::platform::Request *req) { + pthread_mutex_lock(&req->mutex); + if (req->done) { + pthread_mutex_unlock(&req->mutex); + req->foreground_callback(); + pthread_join(req->thread, nullptr); + pthread_mutex_destroy(&req->mutex); + delete req; + dirty = true; + return true; } else { - f_it++; - c_it++; + pthread_mutex_unlock(&req->mutex); + return false; } - } + }); if (dirty) { try { @@ -185,7 +199,7 @@ public: fps(); } - if (dirty || futures.size()) { + if (!requests.empty() || dirty) { glfwPollEvents(); } else { glfwWaitEvents(); @@ -237,29 +251,29 @@ MapView *mapView = nullptr; namespace llmr { namespace platform { -void restart(void *) { +void restart() { if (mapView) { mapView->dirty = true; } } - - static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { - ((std::string*)userp)->append((char*)contents, size *nmemb); + ((std::string *)userp)->append((char *)contents, size * nmemb); return size * nmemb; } -void request_http_async(std::string url, std::function<void(Response&)> func) { - +void *request_http(void *ptr) { + Request *req = static_cast<Request *>(ptr); Response res; + // TODO: use curl multi to be able to cancel + CURL *curl; CURLcode code; curl = curl_easy_init(); if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, req->url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res.body); curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate"); @@ -268,14 +282,33 @@ void request_http_async(std::string url, std::function<void(Response&)> func) { curl_easy_cleanup(curl); } - func(res); + req->background_function(res); + + pthread_mutex_lock(&req->mutex); + req->done = true; + pthread_mutex_unlock(&req->mutex); + + pthread_exit(nullptr); } -void request_http(std::string url, std::function<void(Response&)> func, std::function<void()> cb) { - futures.emplace_back(std::async(std::launch::async, request_http_async, url, func)); - callbacks.push_back(cb); +Request *request_http(std::string url, std::function<void(Response&)> background_function, std::function<void()> foreground_callback) { + Request *req = new Request(); + req->url = url; + req->background_function = background_function; + req->foreground_callback = foreground_callback; + requests.push_front(req); + int rc = pthread_create(&req->thread, nullptr, request_http, (void *)req); + if (rc) { + fprintf(stderr, "http request failed\n"); + return nullptr; + } + + return req; } +void cancel_request_http(Request *request) { + fprintf(stderr, "cancel %p\n", request); +} double time() { return glfwGetTime(); @@ -285,10 +318,13 @@ double time() { } int main() { + curl_global_init(CURL_GLOBAL_ALL); + mapView = new MapView(); mapView->init(); int ret = mapView->run(); mapView->settings.sync(); delete mapView; + pthread_exit(NULL); return ret; } |