mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
IconCache: Add pending state to avoid duplicate downloads in some cases
This commit is contained in:
parent
cb5926761b
commit
2bf2f745e2
3 changed files with 36 additions and 8 deletions
|
@ -33,12 +33,10 @@ void IconCache::SaveToFile(FILE *file) {
|
|||
DiskCacheHeader header;
|
||||
header.magic = ICON_CACHE_MAGIC;
|
||||
header.version = ICON_CACHE_VERSION;
|
||||
header.entryCount = 0; // (uint32_t)cache_.size();
|
||||
header.entryCount = (uint32_t)cache_.size();
|
||||
|
||||
fwrite(&header, 1, sizeof(header), file);
|
||||
|
||||
return;
|
||||
|
||||
for (auto &iter : cache_) {
|
||||
DiskCacheEntry entryHeader;
|
||||
entryHeader.keyLen = (uint32_t)iter.first.size();
|
||||
|
@ -142,6 +140,23 @@ bool IconCache::Contains(const std::string &key) {
|
|||
return cache_.find(key) != cache_.end();
|
||||
}
|
||||
|
||||
bool IconCache::MarkPending(const std::string &key) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
if (cache_.find(key) != cache_.end()) {
|
||||
return false;
|
||||
}
|
||||
if (pending_.find(key) != pending_.end()) {
|
||||
return false;
|
||||
}
|
||||
pending_.insert(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IconCache::Cancel(const std::string &key) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
pending_.erase(key);
|
||||
}
|
||||
|
||||
bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::string &&data) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
|
||||
|
@ -159,6 +174,8 @@ bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::strin
|
|||
return false;
|
||||
}
|
||||
|
||||
pending_.erase(key);
|
||||
|
||||
double now = time_now_d();
|
||||
cache_.emplace(key, Entry{ std::move(data), format, nullptr, now, now, false });
|
||||
return true;
|
||||
|
@ -238,5 +255,7 @@ IconCacheStats IconCache::GetStats() {
|
|||
stats.dataSize += iter.second.data.size();
|
||||
}
|
||||
|
||||
stats.pending = pending_.size();
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <mutex>
|
||||
|
@ -23,6 +24,7 @@ class Texture;
|
|||
struct IconCacheStats {
|
||||
size_t cachedCount;
|
||||
size_t textureCount; // number of cached images that are "live" textures
|
||||
size_t pending;
|
||||
size_t dataSize;
|
||||
};
|
||||
|
||||
|
@ -30,7 +32,9 @@ class IconCache {
|
|||
public:
|
||||
Draw::Texture *BindIconTexture(UIContext *context, const std::string &key);
|
||||
|
||||
// It's okay to call this from any thread.
|
||||
// It's okay to call these from any thread.
|
||||
bool MarkPending(const std::string &key); // returns false if already pending or loaded
|
||||
void Cancel(const std::string &key);
|
||||
bool InsertIcon(const std::string &key, IconFormat format, std::string &&pngData);
|
||||
bool GetDimensions(const std::string &key, int *width, int *height);
|
||||
bool Contains(const std::string &key);
|
||||
|
@ -56,6 +60,7 @@ private:
|
|||
void Decimate();
|
||||
|
||||
std::map<std::string, Entry> cache_;
|
||||
std::set<std::string> pending_;
|
||||
|
||||
std::mutex lock_;
|
||||
};
|
||||
|
|
12
UI/Store.cpp
12
UI/Store.cpp
|
@ -56,12 +56,16 @@ public:
|
|||
HttpImageFileView(http::Downloader *downloader, const std::string &path, UI::ImageSizeMode sizeMode = UI::IS_DEFAULT, bool useIconCache = true, UI::LayoutParams *layoutParams = nullptr)
|
||||
: UI::View(layoutParams), path_(path), sizeMode_(sizeMode), downloader_(downloader), useIconCache_(useIconCache) {
|
||||
|
||||
if (useIconCache && !g_iconCache.Contains(path_)) {
|
||||
if (useIconCache && g_iconCache.MarkPending(path_)) {
|
||||
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
|
||||
downloader_->StartDownloadWithCallback(path_, Path(), [&](http::Download &download) {
|
||||
std::string data;
|
||||
download.buffer().TakeAll(&data);
|
||||
g_iconCache.InsertIcon(path_, IconFormat::PNG, std::move(data));
|
||||
if (download.ResultCode() == 200) {
|
||||
std::string data;
|
||||
download.buffer().TakeAll(&data);
|
||||
g_iconCache.InsertIcon(path_, IconFormat::PNG, std::move(data));
|
||||
} else {
|
||||
g_iconCache.Cancel(path_);
|
||||
}
|
||||
}, acceptMime);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue