aboutsummaryrefslogtreecommitdiff
path: root/include/dchat/Cache.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/dchat/Cache.hpp')
-rw-r--r--include/dchat/Cache.hpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/include/dchat/Cache.hpp b/include/dchat/Cache.hpp
new file mode 100644
index 0000000..debcd5b
--- /dev/null
+++ b/include/dchat/Cache.hpp
@@ -0,0 +1,102 @@
+#pragma once
+
+#include "types.hpp"
+#include "WebPagePreview.hpp"
+#include "StringView.hpp"
+#include <boost/filesystem/path.hpp>
+#include <string>
+#include <unordered_map>
+#include <thread>
+#include <mutex>
+#include <vector>
+#include <chrono>
+#include <functional>
+
+namespace TinyProcessLib
+{
+ class Process;
+}
+
+namespace dchat
+{
+ class Gif;
+ class WebPagePreview;
+
+ struct ContentByUrlResult
+ {
+ enum class Type
+ {
+ CACHED,
+ DOWNLOADING,
+ FAILED_DOWNLOAD
+ };
+
+ enum class CachedType
+ {
+ NONE,
+ TEXTURE_FILEPATH,
+ GIF,
+ WEB_PAGE_PREVIEW
+ };
+
+ ContentByUrlResult() : textureFilePath(nullptr), type(Type::DOWNLOADING), cachedType(CachedType::NONE) {}
+ ContentByUrlResult(boost::filesystem::path *_textureFilePath, Type _type) : textureFilePath(_textureFilePath), type(_type), cachedType(CachedType::TEXTURE_FILEPATH) {}
+ 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
+ {
+ boost::filesystem::path *textureFilePath;
+ Gif *gif;
+ WebPagePreview *webPagePreview;
+ };
+
+ Type type;
+ CachedType cachedType;
+ i64 lastAccessed;
+ };
+
+ using LoadBindsCallbackFunc = std::function<void(const std::string &key, const std::string &value)>;
+ // @fileContent contains data allocated with new[], deallocate it with delete[] fileContent.data;
+ // Returned gif should be allocated with @new
+ using CreateGifFunc = std::function<Gif*(StringView fileContent)>;
+
+ class Cache
+ {
+ public:
+ // @createGifFunc can't be nullptr
+ Cache(CreateGifFunc createGifFunc);
+ ~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<std::string, std::string> &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<ImageDownloadInfo> imageDownloadProcesses;
+ std::vector<ImageDownloadInfo> imageDownloadProcessesQueue;
+ std::mutex imageDownloadMutex;
+ bool alive;
+ std::unordered_map<std::string, ContentByUrlResult> contentUrlCache;
+ CreateGifFunc createGifFunc;
+ };
+}