#pragma once #include "../include/Storage.hpp" #include #include #include #include #include #include #include #include #include #include namespace QuickMedia { enum class LoadingState { NOT_LOADED, LOADING, FINISHED_LOADING, APPLIED_TO_TEXTURE }; struct ThumbnailData { bool referenced = false; LoadingState loading_state = LoadingState::NOT_LOADED; sf::Texture texture; std::unique_ptr image; // Set in another thread. This should be .reset after loading it into |texture|, to save memory sf::Clock texture_applied_time; }; constexpr int NUM_IMAGE_LOAD_THREADS = 4; class AsyncImageLoader { public: AsyncImageLoader(); ~AsyncImageLoader(); // Returns false if the image loader is already loading an image. In that case, this function should be called again later. // set |resize_target_size| to {0, 0} to disable resizing. // |thumbnail_data.loading_state| has to be LoadingState::NOT_LOADED when calling this! // Note: this method is not thread-safe void load_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size, bool use_tor, std::shared_ptr thumbnail_data); private: struct ThumbnailLoadData { Path path; Path thumbnail_path; bool local; std::shared_ptr thumbnail_data; sf::Vector2i resize_target_size; }; // Returns -1 if all threads are busy int get_free_load_index() const; private: bool loading_image[NUM_IMAGE_LOAD_THREADS]; // TODO: Use curl single-threaded multi-download feature instead std::thread download_image_thread[NUM_IMAGE_LOAD_THREADS]; std::thread load_image_thread; std::mutex load_image_mutex; std::condition_variable load_image_cv; std::deque images_to_load; bool running = true; }; }