#pragma once #include #include #include #include #include #include #include namespace TinyProcessLib { class Process; } namespace dchat { class Gif; struct ImageByUrlResult { enum class Type { CACHED, DOWNLOADING, FAILED_DOWNLOAD }; ImageByUrlResult() : texture(nullptr), type(Type::DOWNLOADING), isGif(false) {} ImageByUrlResult(sf::Texture *_texture, Type _type) : texture(_texture), type(_type), isGif(false) {} ImageByUrlResult(Gif *_gif, Type _type) : gif(_gif), type(_type), isGif(true) {} // @texture is null if @type is DOWNLOADING or FAILED_DOWNLOAD union { sf::Texture *texture; Gif *gif; }; Type type; bool isGif; }; class Cache { public: Cache(); ~Cache(); // Creates directory if it doesn't exist (recursively). Throws boost exception on failure static boost::filesystem::path getDchatDir(); static void loadBindsFromFile(); static void replaceBindsInFile(const std::unordered_map &binds); // Get cached image or downloads it. // Default download file limit is 12MB // Returns ImageByUrlResult describing texture status. const ImageByUrlResult getImageByUrl(const std::string &url, int downloadLimitBytes = 12582912); private: struct ImageDownloadInfo { TinyProcessLib::Process *process; std::string url; }; std::thread downloadWaitThread; std::vector imageDownloadProcesses; std::vector imageDownloadProcessesQueue; std::mutex imageDownloadMutex; bool alive; }; }