mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	yuzu: Move GameListWorker to its own source files
This has gotten sufficiently large enough to warrant moving it to its own source files. Especially given it dumps the file_sys headers around code that doesn't use it for the most part. This'll also make it easier to introduce a type alias for the compatibility list, so a large unordered_map type declaration doesn't need to be specified all the time (we don't want to propagate the game_list_p.h include via the main game_list.h header).
This commit is contained in:
		
							parent
							
								
									eadd8b91b2
								
							
						
					
					
						commit
						9238015dd4
					
				
					 6 changed files with 230 additions and 179 deletions
				
			
		|  | @ -76,6 +76,8 @@ add_executable(citra-qt | ||||||
|     game_list.cpp |     game_list.cpp | ||||||
|     game_list.h |     game_list.h | ||||||
|     game_list_p.h |     game_list_p.h | ||||||
|  |     game_list_worker.cpp | ||||||
|  |     game_list_worker.h | ||||||
|     hotkeys.cpp |     hotkeys.cpp | ||||||
|     hotkeys.h |     hotkeys.h | ||||||
|     main.cpp |     main.cpp | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "citra_qt/game_list.h" | #include "citra_qt/game_list.h" | ||||||
| #include "citra_qt/game_list_p.h" | #include "citra_qt/game_list_p.h" | ||||||
|  | #include "citra_qt/game_list_worker.h" | ||||||
| #include "citra_qt/main.h" | #include "citra_qt/main.h" | ||||||
| #include "citra_qt/ui_settings.h" | #include "citra_qt/ui_settings.h" | ||||||
| #include "common/common_paths.h" | #include "common/common_paths.h" | ||||||
|  | @ -30,7 +31,6 @@ | ||||||
| #include "core/file_sys/archive_extsavedata.h" | #include "core/file_sys/archive_extsavedata.h" | ||||||
| #include "core/file_sys/archive_source_sd_savedata.h" | #include "core/file_sys/archive_source_sd_savedata.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/loader/loader.h" |  | ||||||
| 
 | 
 | ||||||
| GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} | ||||||
| 
 | 
 | ||||||
|  | @ -648,11 +648,6 @@ void GameList::LoadInterfaceLayout() { | ||||||
| const QStringList GameList::supported_file_extensions = {"3ds", "3dsx", "elf", "axf", | const QStringList GameList::supported_file_extensions = {"3ds", "3dsx", "elf", "axf", | ||||||
|                                                          "cci", "cxi",  "app"}; |                                                          "cci", "cxi",  "app"}; | ||||||
| 
 | 
 | ||||||
| static bool HasSupportedFileExtension(const std::string& file_name) { |  | ||||||
|     QFileInfo file = QFileInfo(QString::fromStdString(file_name)); |  | ||||||
|     return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void GameList::RefreshGameDirectory() { | void GameList::RefreshGameDirectory() { | ||||||
|     if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) { |     if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) { | ||||||
|         LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list."); |         LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list."); | ||||||
|  | @ -678,123 +673,6 @@ QString GameList::FindGameByProgramID(QStandardItem* current_item, u64 program_i | ||||||
|     return ""; |     return ""; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion, |  | ||||||
|                                              GameListDir* parent_dir) { |  | ||||||
|     const auto callback = [this, recursion, parent_dir](u64* num_entries_out, |  | ||||||
|                                                         const std::string& directory, |  | ||||||
|                                                         const std::string& virtual_name) -> bool { |  | ||||||
|         std::string physical_name = directory + DIR_SEP + virtual_name; |  | ||||||
| 
 |  | ||||||
|         if (stop_processing) |  | ||||||
|             return false; // Breaks the callback loop.
 |  | ||||||
| 
 |  | ||||||
|         bool is_dir = FileUtil::IsDirectory(physical_name); |  | ||||||
|         if (!is_dir && HasSupportedFileExtension(physical_name)) { |  | ||||||
|             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); |  | ||||||
|             if (!loader) |  | ||||||
|                 return true; |  | ||||||
| 
 |  | ||||||
|             u64 program_id = 0; |  | ||||||
|             loader->ReadProgramId(program_id); |  | ||||||
| 
 |  | ||||||
|             u64 extdata_id = 0; |  | ||||||
|             loader->ReadExtdataId(extdata_id); |  | ||||||
| 
 |  | ||||||
|             std::vector<u8> smdh = [program_id, &loader]() -> std::vector<u8> { |  | ||||||
|                 std::vector<u8> original_smdh; |  | ||||||
|                 loader->ReadIcon(original_smdh); |  | ||||||
| 
 |  | ||||||
|                 if (program_id < 0x0004000000000000 || program_id > 0x00040000FFFFFFFF) |  | ||||||
|                     return original_smdh; |  | ||||||
| 
 |  | ||||||
|                 std::string update_path = Service::AM::GetTitleContentPath( |  | ||||||
|                     Service::FS::MediaType::SDMC, program_id + 0x0000000E00000000); |  | ||||||
| 
 |  | ||||||
|                 if (!FileUtil::Exists(update_path)) |  | ||||||
|                     return original_smdh; |  | ||||||
| 
 |  | ||||||
|                 std::unique_ptr<Loader::AppLoader> update_loader = Loader::GetLoader(update_path); |  | ||||||
| 
 |  | ||||||
|                 if (!update_loader) |  | ||||||
|                     return original_smdh; |  | ||||||
| 
 |  | ||||||
|                 std::vector<u8> update_smdh; |  | ||||||
|                 update_loader->ReadIcon(update_smdh); |  | ||||||
|                 return update_smdh; |  | ||||||
|             }(); |  | ||||||
| 
 |  | ||||||
|             if (!Loader::IsValidSMDH(smdh) && UISettings::values.game_list_hide_no_icon) { |  | ||||||
|                 // Skip this invalid entry
 |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); |  | ||||||
| 
 |  | ||||||
|             // The game list uses this as compatibility number for untested games
 |  | ||||||
|             QString compatibility("99"); |  | ||||||
|             if (it != compatibility_list.end()) |  | ||||||
|                 compatibility = it->second.first; |  | ||||||
| 
 |  | ||||||
|             emit EntryReady( |  | ||||||
|                 { |  | ||||||
|                     new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id, |  | ||||||
|                                          extdata_id), |  | ||||||
|                     new GameListItemCompat(compatibility), |  | ||||||
|                     new GameListItemRegion(smdh), |  | ||||||
|                     new GameListItem( |  | ||||||
|                         QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), |  | ||||||
|                     new GameListItemSize(FileUtil::GetSize(physical_name)), |  | ||||||
|                 }, |  | ||||||
|                 parent_dir); |  | ||||||
| 
 |  | ||||||
|         } else if (is_dir && recursion > 0) { |  | ||||||
|             watch_list.append(QString::fromStdString(physical_name)); |  | ||||||
|             AddFstEntriesToGameList(physical_name, recursion - 1, parent_dir); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void GameListWorker::run() { |  | ||||||
|     stop_processing = false; |  | ||||||
|     for (UISettings::GameDir& game_dir : game_dirs) { |  | ||||||
|         if (game_dir.path == "INSTALLED") { |  | ||||||
|             QString path = |  | ||||||
|                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)) + |  | ||||||
|                 "Nintendo " |  | ||||||
|                 "3DS/00000000000000000000000000000000/" |  | ||||||
|                 "00000000000000000000000000000000/title/00040000"; |  | ||||||
|             watch_list.append(path); |  | ||||||
|             GameListDir* game_list_dir = new GameListDir(game_dir, GameListItemType::InstalledDir); |  | ||||||
|             emit DirEntryReady({game_list_dir}); |  | ||||||
|             AddFstEntriesToGameList(path.toStdString(), 2, game_list_dir); |  | ||||||
|         } else if (game_dir.path == "SYSTEM") { |  | ||||||
|             QString path = |  | ||||||
|                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)) + |  | ||||||
|                 "00000000000000000000000000000000/title/00040010"; |  | ||||||
|             watch_list.append(path); |  | ||||||
|             GameListDir* game_list_dir = new GameListDir(game_dir, GameListItemType::SystemDir); |  | ||||||
|             emit DirEntryReady({game_list_dir}); |  | ||||||
|             AddFstEntriesToGameList(path.toStdString(), 2, game_list_dir); |  | ||||||
|         } else { |  | ||||||
|             watch_list.append(game_dir.path); |  | ||||||
|             GameListDir* game_list_dir = new GameListDir(game_dir); |  | ||||||
|             emit DirEntryReady({game_list_dir}); |  | ||||||
|             AddFstEntriesToGameList(game_dir.path.toStdString(), game_dir.deep_scan ? 256 : 0, |  | ||||||
|                                     game_list_dir); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|     emit Finished(watch_list); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void GameListWorker::Cancel() { |  | ||||||
|     this->disconnect(); |  | ||||||
|     stop_processing = true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} { | GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} { | ||||||
|     this->main_window = parent; |     this->main_window = parent; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
|  | #include <QMenu> | ||||||
| #include <QString> | #include <QString> | ||||||
| #include <QWidget> | #include <QWidget> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <atomic> |  | ||||||
| #include <map> | #include <map> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <utility> | #include <utility> | ||||||
|  | @ -59,17 +58,6 @@ static QPixmap GetDefaultIcon(bool large) { | ||||||
|     return icon; |     return icon; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static auto FindMatchingCompatibilityEntry( |  | ||||||
|     const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list, |  | ||||||
|     u64 program_id) { |  | ||||||
|     return std::find_if( |  | ||||||
|         compatibility_list.begin(), compatibility_list.end(), |  | ||||||
|         [program_id](const std::pair<std::string, std::pair<QString, QString>>& element) { |  | ||||||
|             std::string pid = fmt::format("{:016X}", program_id); |  | ||||||
|             return element.first == pid; |  | ||||||
|         }); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Gets the short game title from SMDH data. |  * Gets the short game title from SMDH data. | ||||||
|  * @param smdh SMDH data |  * @param smdh SMDH data | ||||||
|  | @ -373,50 +361,16 @@ public: | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | inline auto FindMatchingCompatibilityEntry( | ||||||
|  * Asynchronous worker object for populating the game list. |     const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list, | ||||||
|  * Communicates with other threads through Qt's signal/slot system. |     u64 program_id) { | ||||||
|  */ |     return std::find_if( | ||||||
| class GameListWorker : public QObject, public QRunnable { |         compatibility_list.begin(), compatibility_list.end(), | ||||||
|     Q_OBJECT |         [program_id](const std::pair<std::string, std::pair<QString, QString>>& element) { | ||||||
| 
 |             std::string pid = fmt::format("{:016X}", program_id); | ||||||
| public: |             return element.first == pid; | ||||||
|     explicit GameListWorker( |         }); | ||||||
|         QList<UISettings::GameDir>& game_dirs, | } | ||||||
|         const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) |  | ||||||
|         : game_dirs(game_dirs), compatibility_list(compatibility_list) {} |  | ||||||
| 
 |  | ||||||
| public slots: |  | ||||||
|     /// Starts the processing of directory tree information.
 |  | ||||||
|     void run() override; |  | ||||||
|     /// Tells the worker that it should no longer continue processing. Thread-safe.
 |  | ||||||
|     void Cancel(); |  | ||||||
| 
 |  | ||||||
| signals: |  | ||||||
|     /**
 |  | ||||||
|      * The `EntryReady` signal is emitted once an entry has been prepared and is ready |  | ||||||
|      * to be added to the game list. |  | ||||||
|      * @param entry_items a list with `QStandardItem`s that make up the columns of the new |  | ||||||
|      * entry. |  | ||||||
|      */ |  | ||||||
|     void DirEntryReady(GameListDir* entry_items); |  | ||||||
|     void EntryReady(QList<QStandardItem*> entry_items, GameListDir* parent_dir); |  | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * After the worker has traversed the game directory looking for entries, this signal is |  | ||||||
|      * emitted with a list of folders that should be watched for changes as well. |  | ||||||
|      */ |  | ||||||
|     void Finished(QStringList watch_list); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     QStringList watch_list; |  | ||||||
|     const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list; |  | ||||||
|     QList<UISettings::GameDir>& game_dirs; |  | ||||||
|     std::atomic_bool stop_processing; |  | ||||||
| 
 |  | ||||||
|     void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion, |  | ||||||
|                                  GameListDir* parent_dir); |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class GameList; | class GameList; | ||||||
| class QHBoxLayout; | class QHBoxLayout; | ||||||
|  |  | ||||||
							
								
								
									
										152
									
								
								src/citra_qt/game_list_worker.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								src/citra_qt/game_list_worker.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,152 @@ | ||||||
|  | // Copyright 2018 yuzu emulator team
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <QDir> | ||||||
|  | #include <QFileInfo> | ||||||
|  | 
 | ||||||
|  | #include "citra_qt/game_list.h" | ||||||
|  | #include "citra_qt/game_list_p.h" | ||||||
|  | #include "citra_qt/game_list_worker.h" | ||||||
|  | #include "citra_qt/ui_settings.h" | ||||||
|  | #include "common/common_paths.h" | ||||||
|  | #include "common/file_util.h" | ||||||
|  | #include "core/hle/service/am/am.h" | ||||||
|  | #include "core/hle/service/fs/archive.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
|  | 
 | ||||||
|  | namespace { | ||||||
|  | bool HasSupportedFileExtension(const std::string& file_name) { | ||||||
|  |     const QFileInfo file = QFileInfo(QString::fromStdString(file_name)); | ||||||
|  |     return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); | ||||||
|  | } | ||||||
|  | } // Anonymous namespace
 | ||||||
|  | 
 | ||||||
|  | GameListWorker::GameListWorker( | ||||||
|  |     QList<UISettings::GameDir>& game_dirs, | ||||||
|  |     const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) | ||||||
|  |     : game_dirs(game_dirs), compatibility_list(compatibility_list) {} | ||||||
|  | 
 | ||||||
|  | GameListWorker::~GameListWorker() = default; | ||||||
|  | 
 | ||||||
|  | void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion, | ||||||
|  |                                              GameListDir* parent_dir) { | ||||||
|  |     const auto callback = [this, recursion, parent_dir](u64* num_entries_out, | ||||||
|  |                                                         const std::string& directory, | ||||||
|  |                                                         const std::string& virtual_name) -> bool { | ||||||
|  |         std::string physical_name = directory + DIR_SEP + virtual_name; | ||||||
|  | 
 | ||||||
|  |         if (stop_processing) | ||||||
|  |             return false; // Breaks the callback loop.
 | ||||||
|  | 
 | ||||||
|  |         bool is_dir = FileUtil::IsDirectory(physical_name); | ||||||
|  |         if (!is_dir && HasSupportedFileExtension(physical_name)) { | ||||||
|  |             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); | ||||||
|  |             if (!loader) | ||||||
|  |                 return true; | ||||||
|  | 
 | ||||||
|  |             u64 program_id = 0; | ||||||
|  |             loader->ReadProgramId(program_id); | ||||||
|  | 
 | ||||||
|  |             u64 extdata_id = 0; | ||||||
|  |             loader->ReadExtdataId(extdata_id); | ||||||
|  | 
 | ||||||
|  |             std::vector<u8> smdh = [program_id, &loader]() -> std::vector<u8> { | ||||||
|  |                 std::vector<u8> original_smdh; | ||||||
|  |                 loader->ReadIcon(original_smdh); | ||||||
|  | 
 | ||||||
|  |                 if (program_id < 0x0004000000000000 || program_id > 0x00040000FFFFFFFF) | ||||||
|  |                     return original_smdh; | ||||||
|  | 
 | ||||||
|  |                 std::string update_path = Service::AM::GetTitleContentPath( | ||||||
|  |                     Service::FS::MediaType::SDMC, program_id + 0x0000000E00000000); | ||||||
|  | 
 | ||||||
|  |                 if (!FileUtil::Exists(update_path)) | ||||||
|  |                     return original_smdh; | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<Loader::AppLoader> update_loader = Loader::GetLoader(update_path); | ||||||
|  | 
 | ||||||
|  |                 if (!update_loader) | ||||||
|  |                     return original_smdh; | ||||||
|  | 
 | ||||||
|  |                 std::vector<u8> update_smdh; | ||||||
|  |                 update_loader->ReadIcon(update_smdh); | ||||||
|  |                 return update_smdh; | ||||||
|  |             }(); | ||||||
|  | 
 | ||||||
|  |             if (!Loader::IsValidSMDH(smdh) && UISettings::values.game_list_hide_no_icon) { | ||||||
|  |                 // Skip this invalid entry
 | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); | ||||||
|  | 
 | ||||||
|  |             // The game list uses this as compatibility number for untested games
 | ||||||
|  |             QString compatibility("99"); | ||||||
|  |             if (it != compatibility_list.end()) | ||||||
|  |                 compatibility = it->second.first; | ||||||
|  | 
 | ||||||
|  |             emit EntryReady( | ||||||
|  |                 { | ||||||
|  |                     new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id, | ||||||
|  |                                          extdata_id), | ||||||
|  |                     new GameListItemCompat(compatibility), | ||||||
|  |                     new GameListItemRegion(smdh), | ||||||
|  |                     new GameListItem( | ||||||
|  |                         QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), | ||||||
|  |                     new GameListItemSize(FileUtil::GetSize(physical_name)), | ||||||
|  |                 }, | ||||||
|  |                 parent_dir); | ||||||
|  | 
 | ||||||
|  |         } else if (is_dir && recursion > 0) { | ||||||
|  |             watch_list.append(QString::fromStdString(physical_name)); | ||||||
|  |             AddFstEntriesToGameList(physical_name, recursion - 1, parent_dir); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GameListWorker::run() { | ||||||
|  |     stop_processing = false; | ||||||
|  |     for (UISettings::GameDir& game_dir : game_dirs) { | ||||||
|  |         if (game_dir.path == "INSTALLED") { | ||||||
|  |             QString path = | ||||||
|  |                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)) + | ||||||
|  |                 "Nintendo " | ||||||
|  |                 "3DS/00000000000000000000000000000000/" | ||||||
|  |                 "00000000000000000000000000000000/title/00040000"; | ||||||
|  |             watch_list.append(path); | ||||||
|  |             GameListDir* game_list_dir = new GameListDir(game_dir, GameListItemType::InstalledDir); | ||||||
|  |             emit DirEntryReady({game_list_dir}); | ||||||
|  |             AddFstEntriesToGameList(path.toStdString(), 2, game_list_dir); | ||||||
|  |         } else if (game_dir.path == "SYSTEM") { | ||||||
|  |             QString path = | ||||||
|  |                 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)) + | ||||||
|  |                 "00000000000000000000000000000000/title/00040010"; | ||||||
|  |             watch_list.append(path); | ||||||
|  |             GameListDir* game_list_dir = new GameListDir(game_dir, GameListItemType::SystemDir); | ||||||
|  |             emit DirEntryReady({game_list_dir}); | ||||||
|  |             AddFstEntriesToGameList(path.toStdString(), 2, game_list_dir); | ||||||
|  |         } else { | ||||||
|  |             watch_list.append(game_dir.path); | ||||||
|  |             GameListDir* game_list_dir = new GameListDir(game_dir); | ||||||
|  |             emit DirEntryReady({game_list_dir}); | ||||||
|  |             AddFstEntriesToGameList(game_dir.path.toStdString(), game_dir.deep_scan ? 256 : 0, | ||||||
|  |                                     game_list_dir); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     emit Finished(watch_list); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GameListWorker::Cancel() { | ||||||
|  |     this->disconnect(); | ||||||
|  |     stop_processing = true; | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								src/citra_qt/game_list_worker.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/citra_qt/game_list_worker.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | ||||||
|  | // Copyright 2018 yuzu emulator team
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <atomic> | ||||||
|  | #include <map> | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | #include <QList> | ||||||
|  | #include <QObject> | ||||||
|  | #include <QRunnable> | ||||||
|  | #include <QString> | ||||||
|  | 
 | ||||||
|  | #include "common/common_types.h" | ||||||
|  | 
 | ||||||
|  | class QStandardItem; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Asynchronous worker object for populating the game list. | ||||||
|  |  * Communicates with other threads through Qt's signal/slot system. | ||||||
|  |  */ | ||||||
|  | class GameListWorker : public QObject, public QRunnable { | ||||||
|  |     Q_OBJECT | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     GameListWorker( | ||||||
|  |         QList<UISettings::GameDir>& game_dirs, | ||||||
|  |         const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list); | ||||||
|  |     ~GameListWorker() override; | ||||||
|  | 
 | ||||||
|  |     /// Starts the processing of directory tree information.
 | ||||||
|  |     void run() override; | ||||||
|  | 
 | ||||||
|  |     /// Tells the worker that it should no longer continue processing. Thread-safe.
 | ||||||
|  |     void Cancel(); | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |     /**
 | ||||||
|  |      * The `EntryReady` signal is emitted once an entry has been prepared and is ready | ||||||
|  |      * to be added to the game list. | ||||||
|  |      * @param entry_items a list with `QStandardItem`s that make up the columns of the new entry. | ||||||
|  |      */ | ||||||
|  |     void DirEntryReady(GameListDir* entry_items); | ||||||
|  |     void EntryReady(QList<QStandardItem*> entry_items, GameListDir* parent_dir); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * After the worker has traversed the game directory looking for entries, this signal is emitted | ||||||
|  |      * with a list of folders that should be watched for changes as well. | ||||||
|  |      */ | ||||||
|  |     void Finished(QStringList watch_list); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion, | ||||||
|  |                                  GameListDir* parent_dir); | ||||||
|  | 
 | ||||||
|  |     QStringList watch_list; | ||||||
|  |     const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list; | ||||||
|  |     QList<UISettings::GameDir>& game_dirs; | ||||||
|  |     std::atomic_bool stop_processing; | ||||||
|  | }; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue