Qt: Use fine-grained cover invalidate in downloader

This commit is contained in:
Stenzek
2025-11-30 21:00:26 +10:00
parent 1fccee229b
commit 259cd846a4
6 changed files with 26 additions and 15 deletions

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
#include "coverdownloadwindow.h"
#include "mainwindow.h"
#include "qthost.h"
#include "qtprogresscallback.h"
@@ -49,22 +50,15 @@ void CoverDownloadWindow::onStartClicked()
m_task = QtAsyncTaskWithProgress::create(
this, [this, urls = std::move(urls), use_serials](ProgressCallback* const progress) {
Error error;
const bool result = GameList::DownloadCovers(urls, use_serials, progress, &error);
const bool result = GameList::DownloadCovers(
urls, use_serials, progress, &error, [](const GameList::Entry* entry, std::string) mutable {
Host::RunOnUIThread([path = entry->path]() { g_main_window->invalidateCoverCacheForPath(path); });
});
return [this, result, error = std::move(error)]() { downloadComplete(result, error); };
});
m_task->connectWidgets(m_ui.status, m_ui.progress, m_ui.start);
connect(m_task, &QtAsyncTaskWithProgress::progressValueUpdated, this, [this]() {
// Limit to once every five seconds, otherwise it's way too flickery.
// Ideally in the future we'd have some way to invalidate only a single cover.
if (m_last_refresh_time.GetTimeSeconds() >= 5.0f)
{
emit coverRefreshRequested();
m_last_refresh_time.Reset();
}
});
m_task->start();
updateEnabled();
@@ -72,7 +66,8 @@ void CoverDownloadWindow::onStartClicked()
void CoverDownloadWindow::downloadComplete(bool result, const Error& error)
{
emit coverRefreshRequested();
g_main_window->refreshGameGridCovers();
m_ui.status->setText(tr("Download complete."));
if (!result)
{

View File

@@ -28,7 +28,6 @@ public:
Q_SIGNALS:
void closed();
void coverRefreshRequested();
protected:
void closeEvent(QCloseEvent* ev) override;

View File

@@ -569,6 +569,12 @@ void GameListModel::invalidateCoverForPath(const std::string& path)
emit dataChanged(mi, mi, {Qt::DecorationRole});
}
void GameListModel::invalidateCoverCacheForPath(const std::string& path)
{
m_cover_pixmap_cache.Remove(path);
invalidateCoverForPath(path);
}
const QPixmap& GameListModel::getCoverForEntry(const GameList::Entry* ge) const
{
CoverPixmapCacheEntry* pm = m_cover_pixmap_cache.Lookup(ge->path);

View File

@@ -125,6 +125,7 @@ public:
const QPixmap* lookupIconPixmapForEntry(const GameList::Entry* ge) const;
const QPixmap& getCoverForEntry(const GameList::Entry* ge) const;
void invalidateCoverCacheForPath(const std::string& path);
Q_SIGNALS:
void coverScaleChanged(float scale);

View File

@@ -2960,6 +2960,16 @@ QIcon MainWindow::getIconForGame(const QString& path)
return m_game_list_widget->getModel()->getIconForGame(path);
}
void MainWindow::invalidateCoverCacheForPath(const std::string& path)
{
m_game_list_widget->getModel()->invalidateCoverCacheForPath(path);
}
void MainWindow::refreshGameGridCovers()
{
m_game_list_widget->getModel()->refreshCovers();
}
void MainWindow::runOnUIThread(const std::function<void()>& func)
{
func();
@@ -3266,8 +3276,6 @@ void MainWindow::onToolsCoverDownloaderTriggered()
if (!m_cover_download_window)
{
m_cover_download_window = new CoverDownloadWindow();
connect(m_cover_download_window, &CoverDownloadWindow::coverRefreshRequested, m_game_list_widget,
&GameListWidget::refreshGridCovers);
connect(m_cover_download_window, &CoverDownloadWindow::closed, this, [this]() {
m_cover_download_window->deleteLater();
m_cover_download_window = nullptr;

View File

@@ -124,6 +124,8 @@ public:
void refreshGameListModel();
void cancelGameListRefresh();
QIcon getIconForGame(const QString& path);
void invalidateCoverCacheForPath(const std::string& path);
void refreshGameGridCovers();
void runOnUIThread(const std::function<void()>& func);
void requestShutdown(bool allow_confirm, bool allow_save_to_state, bool save_state, bool check_safety,