#pragma once #include "types.hpp" #include #include #include #include #include #include #include #include namespace TinyProcessLib { class Process; } namespace dchat { class Gif; class WebPagePreview; struct ContentByUrlResult { enum class Type { CACHED, DOWNLOADING, FAILED_DOWNLOAD }; enum class CachedType { NONE, TEXTURE, GIF, WEB_PAGE_PREVIEW }; ContentByUrlResult() : texture(nullptr), type(Type::DOWNLOADING), cachedType(CachedType::NONE) {} ContentByUrlResult(sf::Texture *_texture, Type _type) : texture(_texture), type(_type), cachedType(CachedType::TEXTURE) {} ContentByUrlResult(Gif *_gif, Type _type) : gif(_gif), type(_type), cachedType(CachedType::GIF) {} ContentByUrlResult(WebPagePreview *_webPagePreview, Type _type) : webPagePreview(_webPagePreview), type(_type), cachedType(CachedType::WEB_PAGE_PREVIEW) {} // @texture is null if @type is DOWNLOADING or FAILED_DOWNLOAD union { sf::Texture *texture; Gif *gif; WebPagePreview *webPagePreview; }; Type type; CachedType cachedType; i64 lastAccessed; }; class Cache { public: Cache(); ~Cache(); // Creates directory if it doesn't exist (recursively). Throws boost exception on failure static boost::filesystem::path getDchatDir(); // Creates directory if it doesn't exist (recursively). Throws boost exception on failure static boost::filesystem::path getImagesDir(); static void loadBindsFromFile(); static void replaceBindsInFile(const std::unordered_map &binds); // Get cached content or download it. // Default download file limit is 12MB // Returns ContentByUrlResult describing texture status. const ContentByUrlResult getContentByUrl(const std::string &url, int downloadLimitBytes = 12582912); private: struct ImageDownloadInfo { TinyProcessLib::Process *process; std::string url; }; std::thread downloadWaitThread; std::thread checkContentAccessTimeThread; std::vector imageDownloadProcesses; std::vector imageDownloadProcessesQueue; std::mutex imageDownloadMutex; bool alive; }; }