From 7587581d1f489d95168fc8d03a992d484e160d5f Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Tue, 25 Feb 2025 22:33:04 -0600 Subject: [PATCH] GameList: Allow recursive scans to be cancelled --- common/FileSystem.cpp | 26 ++++++++++++++++---------- common/FileSystem.h | 2 +- pcsx2/GameList.cpp | 9 ++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/common/FileSystem.cpp b/common/FileSystem.cpp index a096cdbc0f5b8..6948d5bccb4c9 100644 --- a/common/FileSystem.cpp +++ b/common/FileSystem.cpp @@ -1354,7 +1354,7 @@ static u32 TranslateWin32Attributes(u32 Win32Attributes) } static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, const char* path, const char* pattern, - u32 flags, FileSystem::FindResultsArray* results, std::vector& visited) + u32 flags, FileSystem::FindResultsArray* results, std::vector& visited, ProgressCallback* cancel) { std::string search_dir; if (path) @@ -1378,6 +1378,9 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, if (hFind == INVALID_HANDLE_VALUE) return 0; + if (cancel && cancel->IsCancelled()) + return 0; + // small speed optimization for '*' case bool hasWildCards = false; bool wildCardMatchAll = false; @@ -1427,11 +1430,11 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, if (parent_path) { const std::string recurse_dir = fmt::format("{}\\{}", parent_path, path); - nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited); + nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited, cancel); } else { - nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited); + nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited, cancel); } } } @@ -1494,7 +1497,7 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, return nFiles; } -bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results) +bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel) { // has a path if (path[0] == '\0') @@ -1514,7 +1517,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin } // enter the recursive function - if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0) + if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0) return false; if (flags & FILESYSTEM_FIND_SORT_BY_NAME) @@ -2046,7 +2049,7 @@ bool FileSystem::DeleteSymbolicLink(const char* path, Error* error) static_assert(sizeof(off_t) == sizeof(s64)); static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, const char* Path, const char* Pattern, - u32 Flags, FileSystem::FindResultsArray* pResults, std::vector& visited) + u32 Flags, FileSystem::FindResultsArray* pResults, std::vector& visited, ProgressCallback* cancel) { std::string tempStr; if (Path) @@ -2065,6 +2068,9 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co if (!pDir) return 0; + if (cancel && cancel->IsCancelled()) + return 0; + // small speed optimization for '*' case bool hasWildCards = false; bool wildCardMatchAll = false; @@ -2118,11 +2124,11 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co if (ParentPath) { const std::string recursive_dir = fmt::format("{}/{}", ParentPath, Path); - nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited); + nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel); } else { - nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited); + nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel); } } } @@ -2177,7 +2183,7 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co return nFiles; } -bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results) +bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel) { // has a path if (path[0] == '\0') @@ -2197,7 +2203,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin } // enter the recursive function - if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0) + if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0) return false; if (flags & FILESYSTEM_FIND_SORT_BY_NAME) diff --git a/common/FileSystem.h b/common/FileSystem.h index f22d4cc72e499..e0ae881e2c4c9 100644 --- a/common/FileSystem.h +++ b/common/FileSystem.h @@ -67,7 +67,7 @@ namespace FileSystem std::vector GetRootDirectoryList(); /// Search for files - bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results); + bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel = nullptr); /// Stat file bool StatFile(const char* path, struct stat* st); diff --git a/pcsx2/GameList.cpp b/pcsx2/GameList.cpp index 52bbea8063a8e..64bd3373ea1dd 100644 --- a/pcsx2/GameList.cpp +++ b/pcsx2/GameList.cpp @@ -593,15 +593,14 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache, progress->PushState(); progress->SetStatusText(fmt::format( recursive ? TRANSLATE_FS("GameList", "Scanning directory {} (recursively)...") : - TRANSLATE_FS("GameList", "Scanning directory {}..."), - path) - .c_str()); + TRANSLATE_FS("GameList", "Scanning directory {}..."), + path).c_str()); FileSystem::FindResultsArray files; FileSystem::FindFiles(path, "*", recursive ? (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE) : - (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES), - &files); + (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES), + &files, progress); u32 files_scanned = 0; progress->SetProgressRange(static_cast(files.size()));