prefetch images

This commit is contained in:
mrbesen 2022-07-05 19:39:16 +02:00
parent d9ad8cb464
commit 5dd822d332
Signed by untrusted user: MrBesen
GPG Key ID: 596B2350DCD67504
4 changed files with 47 additions and 4 deletions

View File

@ -3,6 +3,7 @@
#include <condition_variable>
#include <functional>
#include <mutex>
#include <set>
#include <string>
#include <thread>
#include <vector>
@ -45,7 +46,7 @@ public:
// might block until champ data is available
const std::vector<ChampData>& getChamps();
// might block until image is downloaded
QPixmap getImage(const std::string& champid, ImageType imgtype = ImageType::SQUARE);
QPixmap getImage(const std::string& champid, ImageType imgtype = ImageType::SQUARE, bool writeMemcache = true);
void getImageAsnyc(const std::string& champid, notifyImgfunc_t func, ImageType imgtype = ImageType::SQUARE);
// might block until champ data is available
const ChampData& getBestMatchingChamp(const std::string& name, int* count = nullptr);
@ -58,6 +59,7 @@ protected:
std::string getImageUrl(const std::string& champid, ImageType type);
std::string getCDNString() const;
void prefetchChampImage(const std::string& champid, ImageType imgtype = ImageType::SQUARE);
void getVersionInternal();
void getChampsInternal();
void startThread();
@ -70,6 +72,7 @@ protected:
std::vector<ChampData> champs;
std::mutex cachedatamutex;
std::condition_variable cachedatacv;
std::set<std::string> notDownloadedImages; // the champions of which the square image is not downloaded yet. Is used to download them on idle
private:
struct Task {

View File

@ -9,6 +9,7 @@ public:
DataDragonImageCache(const std::string& folderextra, const std::string& imageext = ".jpg");
~DataDragonImageCache();
bool hasImage(const std::string& name);
QPixmap getImage(const std::string& name);
void addImageRaw(const QByteArray& arr, const std::string& name);
private:

View File

@ -50,7 +50,7 @@ const std::vector<DataDragon::ChampData>& DataDragon::getChamps() {
return champs;
}
QPixmap DataDragon::getImage(const std::string& champid, ImageType imgtype) {
QPixmap DataDragon::getImage(const std::string& champid, ImageType imgtype, bool writeMemcache) {
if(champid.empty()) return {};
// query mem cache
@ -84,11 +84,16 @@ QPixmap DataDragon::getImage(const std::string& champid, ImageType imgtype) {
// store HDD cache
cache[(int) imgtype].addImageRaw(arr, champid);
// remove from notDownloadedList
notDownloadedImages.erase(champid);
QPixmap decodedImage;
decodedImage.loadFromData(arr);
// store mem cache
memcache.addImage(decodedImage, champid, (int) imgtype);
if(writeMemcache) {
memcache.addImage(decodedImage, champid, (int) imgtype);
}
return decodedImage;
}
@ -228,6 +233,13 @@ std::string DataDragon::getCDNString() const {
return "cdn/" + version + "/";
}
void DataDragon::prefetchChampImage(const std::string& champid, ImageType imgtype) {
if(!cache[(int) imgtype].hasImage(champid)) {
Log::debug << "prefetch " << champid << " type: " << (int) imgtype;
getImage(champid, imgtype, false);
}
}
void DataDragon::getVersionInternal() {
std::unique_lock lock(cachedatamutex);
@ -268,6 +280,7 @@ void DataDragon::getChampsInternal() {
for(auto champit = jchampsdata.constBegin(); champit != jchampsdata.constEnd(); champit++) {
if(champit.value().isObject()) {
champs.emplace_back(champit.value().toObject());
notDownloadedImages.insert(champs.back().id);
}
}
}
@ -305,7 +318,28 @@ void DataDragon::threadLoop() {
{
std::unique_lock lock(tasksmutex);
if(tasks.empty()) {
tasksnotemptycv.wait(lock);
if(notDownloadedImages.empty()) {
tasksnotemptycv.wait(lock);
} else {
Log::note << "DataDragon background thread is idleing - prefetching champion images TODO: " << notDownloadedImages.size();
while(!notDownloadedImages.empty() && tasks.empty()) {
lock.unlock();
auto it = notDownloadedImages.begin();
std::string champid = *it;
notDownloadedImages.erase(it);
prefetchChampImage(champid, ImageType::SQUARE);
lock.lock();
}
if(notDownloadedImages.empty() && tasks.empty()) {
// everything prefetched, but nothing more to do
tasksnotemptycv.wait(lock);
}
}
}
if(tasks.empty()) continue;

View File

@ -15,6 +15,11 @@ DataDragonImageCache::DataDragonImageCache(const std::string& folderextra, const
}
DataDragonImageCache::~DataDragonImageCache() {}
bool DataDragonImageCache::hasImage(const std::string& name) {
QFile file(QString::fromStdString(getFilepath(name)));
return file.size() > 1024; // a image with less than 1KiB? assume it would be readable (r-Permissions)
}
QPixmap DataDragonImageCache::getImage(const std::string& name) {
return QPixmap(QString::fromStdString(getFilepath(name)));
}