Qt: Only load trophy icons on a need to know basis

Also cache existing trophy icons
This commit is contained in:
Megamouse 2021-06-06 10:26:44 +02:00
parent 4ab2e40d8a
commit 70c24a9466
2 changed files with 24 additions and 11 deletions

View File

@ -379,14 +379,7 @@ bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
for (u32 trophy_id = 0; trophy_id < trophy_count; ++trophy_id) for (u32 trophy_id = 0; trophy_id < trophy_count; ++trophy_id)
{ {
// A trophy icon has 3 digits from 000 to 999, for example TROP001.PNG // A trophy icon has 3 digits from 000 to 999, for example TROP001.PNG
const QString path = qstr(fmt::format("%sTROP%03d.PNG", game_trophy_data->path, trophy_id)); game_trophy_data->trophy_image_paths << qstr(fmt::format("%sTROP%03d.PNG", game_trophy_data->path, trophy_id));
QPixmap trophy_icon;
if (!trophy_icon.load(path))
{
gui_log.error("Failed to load trophy icon for trophy %d %s", trophy_id, sstr(path));
}
game_trophy_data->trophy_images.emplace_back(std::move(trophy_icon));
} }
// Get game name // Get game name
@ -542,7 +535,7 @@ void trophy_manager_dialog::ResizeTrophyIcons()
for (int i = 0; i < m_trophy_table->rowCount(); ++i) for (int i = 0; i < m_trophy_table->rowCount(); ++i)
indices.append(i); indices.append(i);
const std::function<QPixmap(const int&)> get_scaled = [this, db_pos, dpr, new_height](const int& i) const std::function<QPixmap(const int&)> get_scaled = [this, data = m_trophies_db.at(db_pos).get(), dpr, new_height](const int& i)
{ {
QTableWidgetItem* item = m_trophy_table->item(i, TrophyColumns::Id); QTableWidgetItem* item = m_trophy_table->item(i, TrophyColumns::Id);
QTableWidgetItem* icon_item = m_trophy_table->item(i, TrophyColumns::Icon); QTableWidgetItem* icon_item = m_trophy_table->item(i, TrophyColumns::Icon);
@ -550,8 +543,24 @@ void trophy_manager_dialog::ResizeTrophyIcons()
{ {
return QPixmap(); return QPixmap();
} }
const int trophy_id = item->text().toInt(); const int trophy_id = item->text().toInt();
const QPixmap icon = m_trophies_db[db_pos]->trophy_images[trophy_id]; QPixmap icon;
{
std::scoped_lock lock(data->mtx);
if (data->trophy_images.contains(trophy_id))
{
icon = data->trophy_images[trophy_id];
}
else if (const QString& path = data->trophy_image_paths[trophy_id]; !icon.load(path))
{
gui_log.error("Failed to load trophy icon for trophy %d (icon='%s')", trophy_id, sstr(path));
}
else
{
data->trophy_images[trophy_id] = icon;
}
}
QPixmap new_icon = QPixmap(icon.size() * dpr); QPixmap new_icon = QPixmap(icon.size() * dpr);
new_icon.setDevicePixelRatio(dpr); new_icon.setDevicePixelRatio(dpr);

View File

@ -11,6 +11,8 @@
#include <QSplitter> #include <QSplitter>
#include <memory> #include <memory>
#include <map>
#include <mutex>
class game_list; class game_list;
class gui_settings; class gui_settings;
@ -20,9 +22,11 @@ struct GameTrophiesData
{ {
std::unique_ptr<TROPUSRLoader> trop_usr; std::unique_ptr<TROPUSRLoader> trop_usr;
rXmlDocument trop_config; // I'd like to use unique but the protocol inside of the function passes around shared pointers.. rXmlDocument trop_config; // I'd like to use unique but the protocol inside of the function passes around shared pointers..
std::vector<QPixmap> trophy_images; std::map<int, QPixmap> trophy_images; // Cache trophy images to avoid loading from disk as much as possible.
QStringList trophy_image_paths;
std::string game_name; std::string game_name;
std::string path; std::string path;
std::mutex mtx;
}; };
enum TrophyColumns enum TrophyColumns