if (loadPath.IsEmpty())
{
// not in our texture cache, so try and load directly and then cache the result
- bool flipped;
- unsigned int width, height;
- CStdString image = CTextureCacheJob::DecodeImageURL(texturePath, width, height, flipped);
-
- if (image.IsEmpty())
- return false; // nothing to load
-
- m_texture = CTextureCacheJob::LoadImage(image, width, height, flipped);
-
+ loadPath = CTextureCache::Get().CacheTexture(texturePath, &m_texture);
if (m_texture)
- CTextureCache::Get().BackgroundCacheTexture(texturePath, m_texture);
+ return true; // we're done
}
- else
+ if (!loadPath.IsEmpty())
{
// direct route - load the image
m_texture = new CTexture();
AddJob(new CTextureCacheJob(url, cacheHash));
}
-void CTextureCache::BackgroundCacheTexture(const CStdString &url, const CBaseTexture *texture)
+CStdString CTextureCache::CacheTexture(const CStdString &url, CBaseTexture **texture)
{
- AddJob(new CTextureCacheJob(url, texture));
+ CSingleLock lock(m_processingSection);
+ if (m_processing.find(url) == m_processing.end())
+ {
+ m_processing.insert(url);
+ lock.Leave();
+ // cache the texture directly
+ CTextureCacheJob job(url);
+ bool success = job.CacheTexture(texture);
+ OnJobComplete(0, success, &job);
+ return success ? GetCachedPath(job.m_details.file) : "";
+ }
+ lock.Leave();
+
+ // wait for currently processing job to end.
+ while (true)
+ {
+ m_completeEvent.WaitMSec(1000);
+ {
+ CSingleLock lock(m_processingSection);
+ if (m_processing.find(url) == m_processing.end())
+ break;
+ }
+ }
+ CStdString cachedHash;
+ return GetCachedImage(url, cachedHash);
}
CStdString CTextureCache::CacheImageFile(const CStdString &url)
{
- // Cache image so that the texture manager can load it.
- CTextureCacheJob job(url, "");
- if (job.DoWork() && !job.m_details.hash.empty())
- {
- AddCachedTexture(url, job.m_details);
- if (g_advancedSettings.m_useDDSFanart && !job.m_details.file.empty())
- AddJob(new CTextureDDSJob(GetCachedPath(job.m_details.file)));
- return GetCachedPath(job.m_details.file);
- }
- return "";
+ return CacheTexture(url);
// TODO: In the future we need a cache job to callback when the image is loaded
// thus automatically updating the images. We'd also need fallback code inside
m_processing.erase(i);
}
+ m_completeEvent.Set();
+
// TODO: call back to the UI indicating that it can update it's image...
if (g_advancedSettings.m_useDDSFanart && !cacheJob->m_details.file.empty())
AddJob(new CTextureDDSJob(GetCachedPath(cacheJob->m_details.file)));
#include "utils/StdString.h"
#include "utils/JobManager.h"
#include "TextureDatabase.h"
+#include "threads/Event.h"
class CBaseTexture;
\sa CheckAndCacheImage
*/
void BackgroundCacheImage(const CStdString &image);
- void BackgroundCacheTexture(const CStdString &image, const CBaseTexture *texture);
+
+ /*! \brief Cache an image to image cache, optionally return the texture
+
+ Caches the given image, returning the texture if the caller wants it.
+
+ \param image url of the image to cache
+ \param texture [out] the loaded image
+ \return cached url of this image
+ \sa CTextureCacheJob::CacheTexture
+ */
+ CStdString CacheTexture(const CStdString &url, CBaseTexture **texture = NULL);
/*! \brief Take image URL and add it to image cache
CTextureDatabase m_database;
std::set<CStdString> m_processing; ///< currently processing list to avoid 2 jobs being processed at once
CCriticalSection m_processingSection;
+ CEvent m_completeEvent; ///< Set whenever a job has finished
};