1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "TextureDatabase.h" 12 #include "threads/Event.h" 13 #include "utils/JobManager.h" 14 15 #include <set> 16 #include <string> 17 #include <vector> 18 19 class CURL; 20 class CTexture; 21 22 /*! 23 \ingroup textures 24 \brief Texture cache class for handling the caching of images. 25 26 Manages the caching of images for use as control textures. Images are cached 27 both as originals (direct copies) and as .dds textures for fast loading. Images 28 may be periodically checked for updates and may be purged from the cache if 29 unused for a set period of time. 30 31 */ 32 class CTextureCache : public CJobQueue 33 { 34 public: 35 /*! 36 \brief The only way through which the global instance of the CTextureCache should be accessed. 37 \return the global instance. 38 */ 39 static CTextureCache &GetInstance(); 40 41 /*! \brief Initialize the texture cache 42 */ 43 void Initialize(); 44 45 /*! \brief Deinitialize the texture cache 46 */ 47 void Deinitialize(); 48 49 /*! \brief Check whether we already have this image cached 50 51 Check and return URL to cached image if it exists; If not, return empty string. 52 If the image is cached, return URL (for original image or .dds version if requested) 53 54 \param image url of the image to check 55 \param needsRecaching [out] whether the image needs recaching. 56 \return cached url of this image 57 \sa GetCachedImage 58 */ 59 std::string CheckCachedImage(const std::string &image, bool &needsRecaching); 60 61 /*! \brief Cache image (if required) using a background job 62 63 Checks firstly whether an image is already cached, and return URL if so [see CheckCacheImage] 64 If the image is not yet in the database, a background job is started to 65 cache the image and add to the database [see CTextureCacheJob] 66 67 \param image url of the image to cache 68 \sa CacheImage 69 */ 70 void BackgroundCacheImage(const std::string &image); 71 72 /*! \brief Cache an image to image cache, optionally return the texture 73 74 Caches the given image, returning the texture if the caller wants it. 75 76 \param image url of the image to cache 77 \param texture [out] the loaded image 78 \param details [out] details of the cached image 79 \return cached url of this image 80 \sa CTextureCacheJob::CacheTexture 81 */ 82 std::string CacheImage(const std::string& image, 83 CTexture** texture = NULL, 84 CTextureDetails* details = NULL); 85 86 /*! \brief Cache an image to image cache if not already cached, returning the image details. 87 \param image url of the image to cache. 88 \param details [out] the image details. 89 \return true if the image is in the cache, false otherwise. 90 \sa CTextureCacheJob::CacheTexture 91 */ 92 bool CacheImage(const std::string &image, CTextureDetails &details); 93 94 /*! \brief Check whether an image is in the cache 95 Note: If the image url won't normally be cached (eg a skin image) this function will return false. 96 \param image url of the image 97 \return true if the image is cached, false otherwise 98 \sa ClearCachedImage 99 */ 100 bool HasCachedImage(const std::string &image); 101 102 /*! \brief clear the cached version of the given image 103 \param image url of the image 104 \sa GetCachedImage 105 */ 106 void ClearCachedImage(const std::string &image, bool deleteSource = false); 107 108 /*! \brief clear the cached version of the image with given id 109 \param database id of the image 110 \sa GetCachedImage 111 */ 112 bool ClearCachedImage(int textureID); 113 114 /*! \brief retrieve a cache file (relative to the cache path) to associate with the given image, excluding extension 115 Use GetCachedPath(GetCacheFile(url)+extension) for the full path to the file. 116 \param url location of the image 117 \return a "unique" filename for the associated cache file, excluding extension 118 */ 119 static std::string GetCacheFile(const std::string &url); 120 121 /*! \brief retrieve the full path of the given cached file 122 \param file name of the file 123 \return full path of the cached file 124 */ 125 static std::string GetCachedPath(const std::string &file); 126 127 /*! \brief check whether an image:// URL may be cached 128 \param url the URL to the image 129 \return true if the given URL may be cached, false otherwise 130 */ 131 static bool CanCacheImageURL(const CURL &url); 132 133 /*! \brief Add this image to the database 134 Thread-safe wrapper of CTextureDatabase::AddCachedTexture 135 \param image url of the original image 136 \param details the texture details to add 137 \return true if we successfully added to the database, false otherwise. 138 */ 139 bool AddCachedTexture(const std::string &image, const CTextureDetails &details); 140 141 /*! \brief Export a (possibly) cached image to a file 142 \param image url of the original image 143 \param destination url of the destination image, excluding extension. 144 \param overwrite whether to overwrite the destination if it exists (TODO: Defaults to false) 145 \return true if we successfully exported the file, false otherwise. 146 */ 147 bool Export(const std::string &image, const std::string &destination, bool overwrite); 148 bool Export(const std::string &image, const std::string &destination); //! @todo BACKWARD COMPATIBILITY FOR MUSIC THUMBS 149 private: 150 // private construction, and no assignments; use the provided singleton methods 151 CTextureCache(); 152 CTextureCache(const CTextureCache&) = delete; 153 CTextureCache const& operator=(CTextureCache const&) = delete; 154 ~CTextureCache() override; 155 156 /*! \brief Check if the given image is a cached image 157 \param image url of the image 158 \return true if this is a cached image, false otherwise. 159 */ 160 bool IsCachedImage(const std::string &image) const; 161 162 /*! \brief retrieve the cached version of the given image (if it exists) 163 \param image url of the image 164 \param details [out] the details of the texture. 165 \param trackUsage whether this call should track usage of the image (defaults to false) 166 \return cached url of this image, empty if none exists 167 \sa ClearCachedImage, CTextureDetails 168 */ 169 std::string GetCachedImage(const std::string &image, CTextureDetails &details, bool trackUsage = false); 170 171 /*! \brief Get an image from the database 172 Thread-safe wrapper of CTextureDatabase::GetCachedTexture 173 \param image url of the original image 174 \param details [out] texture details from the database (if available) 175 \return true if we have a cached version of this image, false otherwise. 176 */ 177 bool GetCachedTexture(const std::string &url, CTextureDetails &details); 178 179 /*! \brief Clear an image from the database 180 Thread-safe wrapper of CTextureDatabase::ClearCachedTexture 181 \param image url of the original image 182 \param cacheFile [out] url of the cached original (if available) 183 \return true if we had a cached version of this image, false otherwise. 184 */ 185 bool ClearCachedTexture(const std::string &url, std::string &cacheFile); 186 bool ClearCachedTexture(int textureID, std::string &cacheFile); 187 188 /*! \brief Increment the use count of a texture 189 Stores locally before calling CTextureDatabase::IncrementUseCount via a CUseCountJob 190 \sa CUseCountJob, CTextureDatabase::IncrementUseCount 191 */ 192 void IncrementUseCount(const CTextureDetails &details); 193 194 /*! \brief Set a previously cached texture as valid in the database 195 Thread-safe wrapper of CTextureDatabase::SetCachedTextureValid 196 \param image url of the original image 197 \param updateable whether this image should be checked for updates 198 \return true if successful, false otherwise. 199 */ 200 bool SetCachedTextureValid(const std::string &url, bool updateable); 201 202 void OnJobComplete(unsigned int jobID, bool success, CJob *job) override; 203 void OnJobProgress(unsigned int jobID, unsigned int progress, unsigned int total, const CJob *job) override; 204 205 /*! \brief Called when a caching job has completed. 206 Removes the job from our processing list, updates the database 207 and fires a DDS job if appropriate. 208 \param success whether the job was successful. 209 \param job the caching job. 210 */ 211 void OnCachingComplete(bool success, CTextureCacheJob *job); 212 213 CCriticalSection m_databaseSection; 214 CTextureDatabase m_database; 215 std::set<std::string> m_processinglist; ///< currently processing list to avoid 2 jobs being processed at once 216 CCriticalSection m_processingSection; 217 CEvent m_completeEvent; ///< Set whenever a job has finished 218 std::vector<CTextureDetails> m_useCounts; ///< Use count tracking 219 CCriticalSection m_useCountSection; 220 }; 221 222