#ifndef MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE #define MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE #include #include #include #include #include #include #include #include #include #include typedef struct uv_loop_s uv_loop_t; namespace mbgl { class Request; class Response; class DefaultFileSource; class SharedRequestBase : private util::noncopyable { protected: MBGL_STORE_THREAD(tid) public: SharedRequestBase(DefaultFileSource *source_, const Resource &resource_) : resource(resource_), source(source_) {} virtual void start(uv_loop_t *loop, std::unique_ptr response = nullptr) = 0; virtual void cancel() = 0; void notify(std::unique_ptr response, FileCache::Hint hint) { MBGL_VERIFY_THREAD(tid); if (source) { source->notify(this, observers, std::shared_ptr(std::move(response)), hint); } } void subscribe(Request *request) { MBGL_VERIFY_THREAD(tid); observers.insert(request); } void unsubscribe(Request *request) { MBGL_VERIFY_THREAD(tid); observers.erase(request); if (abandoned()) { // There are no observers anymore. We are initiating cancelation. if (source) { // First, remove this SharedRequestBase from the source. source->notify(this, observers, nullptr, FileCache::Hint::No); } // Then, initiate cancelation of this request cancel(); } } bool abandoned() const { return observers.empty(); } std::vector removeAllInEnvironment(const Environment &env) { MBGL_VERIFY_THREAD(tid); std::vector result; // Removes all Requests in the supplied environment and returns a list // of them. util::erase_if(observers, [&](Request *req) -> bool { if (&req->env == &env) { result.push_back(req); return true; } else { return false; } }); return result; } protected: virtual ~SharedRequestBase() { MBGL_VERIFY_THREAD(tid); } public: const Resource resource; protected: DefaultFileSource *source = nullptr; private: std::set observers; }; } #endif