From 0a69b42d07a2a541ec472a71e599aa8c81fe3912 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 4 Jan 2018 15:03:14 +0100 Subject: [PATCH] DolphinQt2: Perform more of GameTracker's work on a separate thread This reduces the time from startup to the game list window showing up. --- .../Core/DolphinQt2/GameList/GameTracker.cpp | 86 +++++++++++++------ Source/Core/DolphinQt2/GameList/GameTracker.h | 23 ++++- 2 files changed, 83 insertions(+), 26 deletions(-) diff --git a/Source/Core/DolphinQt2/GameList/GameTracker.cpp b/Source/Core/DolphinQt2/GameList/GameTracker.cpp index 94000057b6..64fcaf2d32 100644 --- a/Source/Core/DolphinQt2/GameList/GameTracker.cpp +++ b/Source/Core/DolphinQt2/GameList/GameTracker.cpp @@ -22,22 +22,61 @@ GameTracker::GameTracker(QObject* parent) : QFileSystemWatcher(parent) connect(this, &QFileSystemWatcher::directoryChanged, this, &GameTracker::UpdateDirectory); connect(this, &QFileSystemWatcher::fileChanged, this, &GameTracker::UpdateFile); - m_cache.Load(); + m_load_thread.Reset([this](Command command) { + switch (command.type) + { + case CommandType::LoadCache: + m_cache.Load(); + break; + case CommandType::AddDirectory: + AddDirectoryInternal(command.path); + break; + case CommandType::RemoveDirectory: + RemoveDirectoryInternal(command.path); + break; + case CommandType::UpdateDirectory: + UpdateDirectoryInternal(command.path); + break; + case CommandType::UpdateFile: + UpdateFileInternal(command.path); + break; + } + }); - m_load_thread.Reset([this](const QString& path) { LoadGame(path); }); + m_load_thread.EmplaceItem(Command{CommandType::LoadCache, {}}); // TODO: When language changes, reload m_title_database and call m_cache.UpdateAdditionalMetadata } void GameTracker::AddDirectory(const QString& dir) { - if (!QFileInfo(dir).exists()) - return; - addPath(dir); - UpdateDirectory(dir); + m_load_thread.EmplaceItem(Command{CommandType::AddDirectory, dir}); } void GameTracker::RemoveDirectory(const QString& dir) +{ + m_load_thread.EmplaceItem(Command{CommandType::RemoveDirectory, dir}); +} + +void GameTracker::UpdateDirectory(const QString& dir) +{ + m_load_thread.EmplaceItem(Command{CommandType::UpdateDirectory, dir}); +} + +void GameTracker::UpdateFile(const QString& dir) +{ + m_load_thread.EmplaceItem(Command{CommandType::UpdateFile, dir}); +} + +void GameTracker::AddDirectoryInternal(const QString& dir) +{ + if (!QFileInfo(dir).exists()) + return; + addPath(dir); + UpdateDirectoryInternal(dir); +} + +void GameTracker::RemoveDirectoryInternal(const QString& dir) { removePath(dir); QDirIterator it(dir, game_filters, QDir::NoFilter, QDirIterator::Subdirectories); @@ -57,7 +96,7 @@ void GameTracker::RemoveDirectory(const QString& dir) } } -void GameTracker::UpdateDirectory(const QString& dir) +void GameTracker::UpdateDirectoryInternal(const QString& dir) { QDirIterator it(dir, game_filters, QDir::NoFilter, QDirIterator::Subdirectories); while (it.hasNext()) @@ -74,7 +113,7 @@ void GameTracker::UpdateDirectory(const QString& dir) { addPath(path); m_tracked_files[path] = QSet{dir}; - m_load_thread.EmplaceItem(path); + LoadGame(path); } } @@ -91,6 +130,21 @@ void GameTracker::UpdateDirectory(const QString& dir) } } +void GameTracker::UpdateFileInternal(const QString& file) +{ + if (QFileInfo(file).exists()) + { + GameRemoved(file); + addPath(file); + LoadGame(file); + } + else if (removePath(file)) + { + m_tracked_files.remove(file); + emit GameRemoved(file); + } +} + QSet GameTracker::FindMissingFiles(const QString& dir) { QDirIterator it(dir, game_filters, QDir::NoFilter, QDirIterator::Subdirectories); @@ -113,22 +167,6 @@ QSet GameTracker::FindMissingFiles(const QString& dir) return missing_files; } -void GameTracker::UpdateFile(const QString& file) -{ - if (QFileInfo(file).exists()) - { - GameRemoved(file); - addPath(file); - - m_load_thread.EmplaceItem(file); - } - else if (removePath(file)) - { - m_tracked_files.remove(file); - emit GameRemoved(file); - } -} - void GameTracker::LoadGame(const QString& path) { const std::string converted_path = path.toStdString(); diff --git a/Source/Core/DolphinQt2/GameList/GameTracker.h b/Source/Core/DolphinQt2/GameList/GameTracker.h index 500f1b9aac..73d1e097c4 100644 --- a/Source/Core/DolphinQt2/GameList/GameTracker.h +++ b/Source/Core/DolphinQt2/GameList/GameTracker.h @@ -34,14 +34,33 @@ signals: void GameRemoved(const QString& path); private: - void LoadGame(const QString& path); void UpdateDirectory(const QString& dir); void UpdateFile(const QString& path); + void AddDirectoryInternal(const QString& dir); + void RemoveDirectoryInternal(const QString& dir); + void UpdateDirectoryInternal(const QString& dir); + void UpdateFileInternal(const QString& path); QSet FindMissingFiles(const QString& dir); + void LoadGame(const QString& path); + + enum class CommandType + { + LoadCache, + AddDirectory, + RemoveDirectory, + UpdateDirectory, + UpdateFile, + }; + + struct Command + { + CommandType type; + QString path; + }; // game path -> directories that track it QMap> m_tracked_files; - Common::WorkQueueThread m_load_thread; + Common::WorkQueueThread m_load_thread; UICommon::GameFileCache m_cache; Core::TitleDatabase m_title_database; };