#pragma once #include "types.hpp" #include "WebPagePreview.hpp" #include "StringView.hpp" #include "utils.hpp" #include #include #include #include #include #include #include #include namespace TinyProcessLib { class Process; } namespace dchat { class Gif; class StaticImage; class WebPagePreview; struct ContentByUrlResult { enum class Type { CACHED, DOWNLOADING, FAILED_DOWNLOAD }; enum class CachedType { NONE, STATIC_IMAGE, GIF, WEB_PAGE_PREVIEW }; ContentByUrlResult() : staticImage(nullptr), type(Type::DOWNLOADING), cachedType(CachedType::NONE) {} ContentByUrlResult(StaticImage *_staticImage, Type _type) : staticImage(_staticImage), type(_type), cachedType(CachedType::STATIC_IMAGE) {} 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 { StaticImage *staticImage; Gif *gif; WebPagePreview *webPagePreview; }; Type type; CachedType cachedType; i64 lastAccessed; }; using LoadBindsCallbackFunc = std::function; // @fileContent contains data allocated with new[], deallocate it with delete[] fileContent.data; // Returned gif should be allocated with @new using CreateGifFunc = std::function; using CreateStaticImageFunc = std::function; class Cache { DISABLE_COPY(Cache) public: // @createGifFunc can't be null // @createStaticImageFunc can't be null Cache(CreateGifFunc createGifFunc, CreateStaticImageFunc createStaticImageFunc); ~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(); // @callbackFunc can't be nullptr static void loadBindsFromFile(LoadBindsCallbackFunc callbackFunc); 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; std::unordered_map contentUrlCache; CreateGifFunc createGifFunc; CreateStaticImageFunc createStaticImageFunc; }; }