mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Improved responsiveness when refreshing game list.
This commit is contained in:
@ -203,9 +203,13 @@ void GameList::UpdateColumnVisibility()
|
||||
|
||||
void GameList::MakeEmptyView()
|
||||
{
|
||||
const QString refreshing_msg = tr("Refreshing...");
|
||||
const QString empty_msg = tr("Dolphin could not find any GameCube/Wii ISOs or WADs.\n"
|
||||
"Double-click here to set a games directory...");
|
||||
|
||||
m_empty = new QLabel(this);
|
||||
m_empty->setText(tr("Dolphin could not find any GameCube/Wii ISOs or WADs.\n"
|
||||
"Double-click here to set a games directory..."));
|
||||
m_empty->setText(refreshing_msg);
|
||||
m_empty->setEnabled(false);
|
||||
m_empty->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
|
||||
auto event_filter = new DoubleClickEventFilter{m_empty};
|
||||
@ -216,6 +220,21 @@ void GameList::MakeEmptyView()
|
||||
if (!dir.isEmpty())
|
||||
Settings::Instance().AddPath(dir);
|
||||
});
|
||||
|
||||
QSizePolicy size_policy{m_empty->sizePolicy()};
|
||||
size_policy.setRetainSizeWhenHidden(true);
|
||||
m_empty->setSizePolicy(size_policy);
|
||||
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshRequested, this,
|
||||
[this, refreshing_msg = refreshing_msg] {
|
||||
m_empty->setText(refreshing_msg);
|
||||
m_empty->setEnabled(false);
|
||||
});
|
||||
connect(&Settings::Instance(), &Settings::GameListRefreshCompleted, this,
|
||||
[this, empty_msg = empty_msg] {
|
||||
m_empty->setText(empty_msg);
|
||||
m_empty->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
void GameList::resizeEvent(QResizeEvent* event)
|
||||
|
@ -35,7 +35,10 @@ GameTracker::GameTracker(QObject* parent) : QFileSystemWatcher(parent)
|
||||
qRegisterMetaType<std::shared_ptr<const UICommon::GameFile>>();
|
||||
qRegisterMetaType<std::string>();
|
||||
|
||||
connect(qApp, &QApplication::aboutToQuit, this, [this] { m_load_thread.Cancel(); });
|
||||
connect(qApp, &QApplication::aboutToQuit, this, [this] {
|
||||
m_processing_halted = true;
|
||||
m_load_thread.Cancel();
|
||||
});
|
||||
connect(this, &QFileSystemWatcher::directoryChanged, this, &GameTracker::UpdateDirectory);
|
||||
connect(this, &QFileSystemWatcher::fileChanged, this, &GameTracker::UpdateFile);
|
||||
connect(&Settings::Instance(), &Settings::AutoRefreshToggled, this, [] {
|
||||
@ -75,27 +78,24 @@ GameTracker::GameTracker(QObject* parent) : QFileSystemWatcher(parent)
|
||||
break;
|
||||
case CommandType::UpdateMetadata:
|
||||
m_cache.UpdateAdditionalMetadata(
|
||||
[this](const std::shared_ptr<const UICommon::GameFile>& game) {
|
||||
emit GameUpdated(game);
|
||||
});
|
||||
[this](const std::shared_ptr<const UICommon::GameFile>& game) { emit GameUpdated(game); },
|
||||
m_processing_halted);
|
||||
QueueOnObject(this, [] { Settings::Instance().NotifyMetadataRefreshComplete(); });
|
||||
break;
|
||||
case CommandType::ResumeProcessing:
|
||||
m_processing_halted = false;
|
||||
break;
|
||||
case CommandType::PurgeCache:
|
||||
m_cache.Clear(UICommon::GameFileCache::DeleteOnDisk::Yes);
|
||||
break;
|
||||
case CommandType::BeginRefresh:
|
||||
if (m_busy_count++ == 0)
|
||||
{
|
||||
for (auto& file : m_tracked_files.keys())
|
||||
emit GameRemoved(file.toStdString());
|
||||
m_tracked_files.clear();
|
||||
}
|
||||
QueueOnObject(this, [] { Settings::Instance().NotifyRefreshGameListStarted(); });
|
||||
for (auto& file : m_tracked_files.keys())
|
||||
emit GameRemoved(file.toStdString());
|
||||
m_tracked_files.clear();
|
||||
break;
|
||||
case CommandType::EndRefresh:
|
||||
if (--m_busy_count == 0)
|
||||
{
|
||||
QueueOnObject(this, [] { Settings::Instance().NotifyRefreshGameListComplete(); });
|
||||
}
|
||||
QueueOnObject(this, [] { Settings::Instance().NotifyRefreshGameListComplete(); });
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -135,6 +135,8 @@ void GameTracker::StartInternal()
|
||||
|
||||
m_started = true;
|
||||
|
||||
QueueOnObject(this, [] { Settings::Instance().NotifyRefreshGameListStarted(); });
|
||||
|
||||
std::vector<std::string> paths;
|
||||
paths.reserve(m_tracked_files.size());
|
||||
for (const QString& path : m_tracked_files.keys())
|
||||
@ -150,8 +152,9 @@ void GameTracker::StartInternal()
|
||||
|
||||
m_initial_games_emitted_event.Wait();
|
||||
|
||||
bool cache_updated = m_cache.Update(paths, emit_game_loaded, emit_game_removed);
|
||||
cache_updated |= m_cache.UpdateAdditionalMetadata(emit_game_updated);
|
||||
bool cache_updated =
|
||||
m_cache.Update(paths, emit_game_loaded, emit_game_removed, m_processing_halted);
|
||||
cache_updated |= m_cache.UpdateAdditionalMetadata(emit_game_updated, m_processing_halted);
|
||||
if (cache_updated)
|
||||
m_cache.Save();
|
||||
|
||||
@ -196,6 +199,16 @@ void GameTracker::RemoveDirectory(const QString& dir)
|
||||
|
||||
void GameTracker::RefreshAll()
|
||||
{
|
||||
m_processing_halted = true;
|
||||
m_load_thread.Clear();
|
||||
m_load_thread.EmplaceItem(Command{CommandType::ResumeProcessing, {}});
|
||||
|
||||
if (m_needs_purge)
|
||||
{
|
||||
m_load_thread.EmplaceItem(Command{CommandType::PurgeCache, {}});
|
||||
m_needs_purge = false;
|
||||
}
|
||||
|
||||
m_load_thread.EmplaceItem(Command{CommandType::BeginRefresh});
|
||||
|
||||
for (const QString& dir : Settings::Instance().GetPaths())
|
||||
@ -257,7 +270,7 @@ void GameTracker::RemoveDirectoryInternal(const QString& dir)
|
||||
void GameTracker::UpdateDirectoryInternal(const QString& dir)
|
||||
{
|
||||
auto it = GetIterator(dir);
|
||||
while (it->hasNext() && !m_load_thread.IsCancelled())
|
||||
while (it->hasNext() && !m_processing_halted)
|
||||
{
|
||||
QString path = QFileInfo(it->next()).canonicalFilePath();
|
||||
|
||||
@ -277,6 +290,9 @@ void GameTracker::UpdateDirectoryInternal(const QString& dir)
|
||||
|
||||
for (const auto& missing : FindMissingFiles(dir))
|
||||
{
|
||||
if (m_processing_halted)
|
||||
break;
|
||||
|
||||
auto& tracked_file = m_tracked_files[missing];
|
||||
|
||||
tracked_file.remove(dir);
|
||||
@ -347,6 +363,6 @@ void GameTracker::LoadGame(const QString& path)
|
||||
|
||||
void GameTracker::PurgeCache()
|
||||
{
|
||||
m_load_thread.EmplaceItem(Command{CommandType::PurgeCache, {}});
|
||||
m_needs_purge = true;
|
||||
Settings::Instance().RefreshGameList();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@ -72,6 +73,7 @@ private:
|
||||
UpdateDirectory,
|
||||
UpdateFile,
|
||||
UpdateMetadata,
|
||||
ResumeProcessing,
|
||||
PurgeCache,
|
||||
BeginRefresh,
|
||||
EndRefresh,
|
||||
@ -92,8 +94,8 @@ private:
|
||||
Common::Event m_initial_games_emitted_event;
|
||||
bool m_initial_games_emitted = false;
|
||||
bool m_started = false;
|
||||
// Count of currently running refresh jobs
|
||||
u32 m_busy_count = 0;
|
||||
bool m_needs_purge = false;
|
||||
std::atomic_bool m_processing_halted = false;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<const UICommon::GameFile>)
|
||||
|
Reference in New Issue
Block a user