#include #include #include #include #include #include namespace mbgl { FileSource::FileSource(uv_loop_t *loop_) : thread_id(uv_thread_self()), store(std::shared_ptr(new SQLiteStore(loop_, "cache.db"))), loop(loop_), queue(new uv_messenger_t) { uv_messenger_init(loop, queue, [](void *ptr) { std::unique_ptr> fn { reinterpret_cast *>(ptr) }; (*fn)(); }); } FileSource::~FileSource() { assert(thread_id == uv_thread_self()); uv_messenger_stop(queue); // NOTE: We don't need to delete the messenger since it will be deleted by the // uv_messenger_stop() function. } void FileSource::setBase(const std::string &value) { assert(thread_id == uv_thread_self()); base = value; } const std::string &FileSource::getBase() const { assert(thread_id == uv_thread_self()); return base; } std::unique_ptr FileSource::request(ResourceType type, const std::string &url) { assert(thread_id == uv_thread_self()); // Make URL absolute. const std::string absoluteURL = [&]() -> std::string { const size_t separator = url.find("://"); if (separator == std::string::npos) { // Relative URL. return base + url; } else { return url; } }(); std::shared_ptr request; // First, try to find an existing Request object. auto it = pending.find(absoluteURL); if (it != pending.end()) { request = it->second.lock(); } if (!request) { if (absoluteURL.substr(0, 7) == "file://") { request = std::make_shared(absoluteURL.substr(7), loop); } else { request = std::make_shared(type, absoluteURL, loop, store); } pending.emplace(absoluteURL, request); } return std::unique_ptr(new Request(request)); } void FileSource::prepare(std::function fn) { if (thread_id == uv_thread_self()) { fn(); } else { uv_messenger_send(queue, new std::function(std::move(fn))); } } }