#pragma once #include #include #include #include #include #include #include #include #include #include "util.hpp" #include "http.hpp" class FileCacheWorkerThread { public: using callback_type = sigc::slot; FileCacheWorkerThread(); ~FileCacheWorkerThread(); void set_file_path(const std::filesystem::path &path); void add_image(const std::string &string, callback_type callback); void stop(); private: void loop(); bool m_stop = false; std::thread m_thread; struct QueueEntry { std::string URL; callback_type Callback; }; std::condition_variable m_cv; mutable std::mutex m_queue_mutex; std::queue m_queue; std::unordered_map m_curl_file_handles; std::unordered_map m_handle_urls; std::unordered_map m_paths; std::unordered_map m_callbacks; int m_running_handles = 0; std::unordered_set m_handles; CURLM *m_multi_handle; std::filesystem::path m_data_path; }; class Cache { public: Cache(); ~Cache(); using callback_type = std::function; void GetFileFromURL(std::string url, callback_type cb); std::string GetPathIfCached(std::string url); void ClearCache(); private: void CleanupFutures(); void RespondFromPath(std::filesystem::path path, callback_type cb); void OnResponse(const std::string &url); void OnFetchComplete(const std::string &url); std::unordered_map> m_callbacks; std::vector> m_futures; std::filesystem::path m_tmp_path; mutable std::mutex m_mutex; FileCacheWorkerThread m_worker; };