#pragma once #include "types.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; }; // @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; using CreateWebPagePreviewFunc = std::function; class Cache { DISABLE_COPY(Cache) public: // @createGifFunc can't be null // @createStaticImageFunc can't be null // @createWebPagePreviewFunc can't be null Cache(CreateGifFunc createGifFunc, CreateStaticImageFunc createStaticImageFunc, CreateWebPagePreviewFunc createWebPagePreviewFunc); ~Cache(); // 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: ContentByUrlResult loadImageFromFile(const boost::filesystem::path &filepath, bool loadFromCache); 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; CreateWebPagePreviewFunc createWebPagePreviewFunc; }; }