summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Emmanuel Gil Peyrot2015-09-06 07:59:04 +0100
committerGravatar Emmanuel Gil Peyrot2016-05-21 16:41:02 +0100
commit8ab6f26c09e5b77a051fa545570ca2986c45bf4a (patch)
treea0664d2b9bb548cbd7f78ed60b846a88c09f90f4 /src
parentAppveyor: Restore working directory after test_script (#1835) (diff)
downloadyuzu-8ab6f26c09e5b77a051fa545570ca2986c45bf4a.tar.gz
yuzu-8ab6f26c09e5b77a051fa545570ca2986c45bf4a.tar.xz
yuzu-8ab6f26c09e5b77a051fa545570ca2986c45bf4a.zip
Common: Make recursive FileUtil functions take a maximum recursion
Fixes #1115. Also improves the performances of DiskArchive’s directory implementation a lot, simply by not going through the entire tree instead of just listing the first level files. Thanks to JayRoxFox for rebasing this on current master!
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/game_list.cpp11
-rw-r--r--src/citra_qt/game_list_p.h2
-rw-r--r--src/common/file_util.cpp48
-rw-r--r--src/common/file_util.h12
4 files changed, 43 insertions, 30 deletions
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index d4ac9c96e..adbcf24e8 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -118,19 +118,20 @@ void GameList::LoadInterfaceLayout()
118 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); 118 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
119} 119}
120 120
121void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, bool deep_scan) 121void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion)
122{ 122{
123 const auto callback = [&](unsigned* num_entries_out, 123 const auto callback = [&](unsigned* num_entries_out,
124 const std::string& directory, 124 const std::string& directory,
125 const std::string& virtual_name) -> bool { 125 const std::string& virtual_name,
126 unsigned int recursion) -> bool {
126 127
127 std::string physical_name = directory + DIR_SEP + virtual_name; 128 std::string physical_name = directory + DIR_SEP + virtual_name;
128 129
129 if (stop_processing) 130 if (stop_processing)
130 return false; // Breaks the callback loop. 131 return false; // Breaks the callback loop.
131 132
132 if (deep_scan && FileUtil::IsDirectory(physical_name)) { 133 if (recursion > 0 && FileUtil::IsDirectory(physical_name)) {
133 AddFstEntriesToGameList(physical_name, true); 134 AddFstEntriesToGameList(physical_name, recursion - 1);
134 } else { 135 } else {
135 std::string filename_filename, filename_extension; 136 std::string filename_filename, filename_extension;
136 Common::SplitPath(physical_name, nullptr, &filename_filename, &filename_extension); 137 Common::SplitPath(physical_name, nullptr, &filename_filename, &filename_extension);
@@ -169,7 +170,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, bool d
169void GameListWorker::run() 170void GameListWorker::run()
170{ 171{
171 stop_processing = false; 172 stop_processing = false;
172 AddFstEntriesToGameList(dir_path.toStdString(), deep_scan); 173 AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0);
173 emit Finished(); 174 emit Finished();
174} 175}
175 176
diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h
index 284f5da81..2d6b8aae0 100644
--- a/src/citra_qt/game_list_p.h
+++ b/src/citra_qt/game_list_p.h
@@ -212,5 +212,5 @@ private:
212 bool deep_scan; 212 bool deep_scan;
213 std::atomic_bool stop_processing; 213 std::atomic_bool stop_processing;
214 214
215 void AddFstEntriesToGameList(const std::string& dir_path, bool deep_scan); 215 void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0);
216}; 216};
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 6e2867658..17af7c385 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -434,7 +434,7 @@ bool CreateEmptyFile(const std::string &filename)
434} 434}
435 435
436 436
437bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback) 437bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback, unsigned int recursion)
438{ 438{
439 LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); 439 LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str());
440 440
@@ -472,7 +472,7 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo
472 continue; 472 continue;
473 473
474 unsigned ret_entries = 0; 474 unsigned ret_entries = 0;
475 if (!callback(&ret_entries, directory, virtual_name)) { 475 if (!callback(&ret_entries, directory, virtual_name, recursion)) {
476 callback_error = true; 476 callback_error = true;
477 break; 477 break;
478 } 478 }
@@ -486,30 +486,34 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo
486 closedir(dirp); 486 closedir(dirp);
487#endif 487#endif
488 488
489 if (!callback_error) { 489 if (callback_error)
490 // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it
491 if (num_entries_out != nullptr)
492 *num_entries_out = found_entries;
493 return true;
494 } else {
495 return false; 490 return false;
496 } 491
492 // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it
493 if (num_entries_out != nullptr)
494 *num_entries_out = found_entries;
495 return true;
497} 496}
498 497
499unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry) 498unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, unsigned int recursion)
500{ 499{
501 const auto callback = [&parent_entry](unsigned* num_entries_out, 500 const auto callback = [&parent_entry](unsigned* num_entries_out,
502 const std::string& directory, 501 const std::string& directory,
503 const std::string& virtual_name) -> bool { 502 const std::string& virtual_name,
503 unsigned int recursion) -> bool {
504 FSTEntry entry; 504 FSTEntry entry;
505 entry.virtualName = virtual_name; 505 entry.virtualName = virtual_name;
506 entry.physicalName = directory + DIR_SEP + virtual_name; 506 entry.physicalName = directory + DIR_SEP + virtual_name;
507 507
508 if (IsDirectory(entry.physicalName)) { 508 if (IsDirectory(entry.physicalName)) {
509 entry.isDirectory = true; 509 entry.isDirectory = true;
510 // is a directory, lets go inside 510 // is a directory, lets go inside if we didn't recurse to often
511 entry.size = ScanDirectoryTree(entry.physicalName, entry); 511 if (recursion > 0) {
512 *num_entries_out += (int)entry.size; 512 entry.size = ScanDirectoryTree(entry.physicalName, entry, recursion - 1);
513 *num_entries_out += (int)entry.size;
514 } else {
515 entry.size = 0;
516 }
513 } else { // is a file 517 } else { // is a file
514 entry.isDirectory = false; 518 entry.isDirectory = false;
515 entry.size = GetSize(entry.physicalName); 519 entry.size = GetSize(entry.physicalName);
@@ -522,23 +526,27 @@ unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry)
522 }; 526 };
523 527
524 unsigned num_entries; 528 unsigned num_entries;
525 return ForeachDirectoryEntry(&num_entries, directory, callback) ? num_entries : 0; 529 return ForeachDirectoryEntry(&num_entries, directory, callback, recursion) ? num_entries : 0;
526} 530}
527 531
528 532
529bool DeleteDirRecursively(const std::string &directory) 533bool DeleteDirRecursively(const std::string &directory, unsigned int recursion)
530{ 534{
531 const static auto callback = [](unsigned* num_entries_out, 535 const static auto callback = [](unsigned* num_entries_out,
532 const std::string& directory, 536 const std::string& directory,
533 const std::string& virtual_name) -> bool { 537 const std::string& virtual_name,
538 unsigned int recursion) -> bool {
534 std::string new_path = directory + DIR_SEP_CHR + virtual_name; 539 std::string new_path = directory + DIR_SEP_CHR + virtual_name;
535 if (IsDirectory(new_path))
536 return DeleteDirRecursively(new_path);
537 540
541 if (IsDirectory(new_path)) {
542 if (recursion == 0)
543 return false;
544 return DeleteDirRecursively(new_path, recursion - 1);
545 }
538 return Delete(new_path); 546 return Delete(new_path);
539 }; 547 };
540 548
541 if (!ForeachDirectoryEntry(nullptr, directory, callback)) 549 if (!ForeachDirectoryEntry(nullptr, directory, callback, recursion))
542 return false; 550 return false;
543 551
544 // Delete the outermost directory 552 // Delete the outermost directory
diff --git a/src/common/file_util.h b/src/common/file_util.h
index c6a8694ce..32ae2dc57 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -105,11 +105,13 @@ bool CreateEmptyFile(const std::string &filename);
105 * @param num_entries_out to be assigned by the callable with the number of iterated directory entries, never null 105 * @param num_entries_out to be assigned by the callable with the number of iterated directory entries, never null
106 * @param directory the path to the enclosing directory 106 * @param directory the path to the enclosing directory
107 * @param virtual_name the entry name, without any preceding directory info 107 * @param virtual_name the entry name, without any preceding directory info
108 * @param recursion Number of children directory to read before giving up
108 * @return whether handling the entry succeeded 109 * @return whether handling the entry succeeded
109 */ 110 */
110using DirectoryEntryCallable = std::function<bool(unsigned* num_entries_out, 111using DirectoryEntryCallable = std::function<bool(unsigned* num_entries_out,
111 const std::string& directory, 112 const std::string& directory,
112 const std::string& virtual_name)>; 113 const std::string& virtual_name,
114 unsigned int recursion)>;
113 115
114/** 116/**
115 * Scans a directory, calling the callback for each file/directory contained within. 117 * Scans a directory, calling the callback for each file/directory contained within.
@@ -117,20 +119,22 @@ using DirectoryEntryCallable = std::function<bool(unsigned* num_entries_out,
117 * @param num_entries_out assigned by the function with the number of iterated directory entries, can be null 119 * @param num_entries_out assigned by the function with the number of iterated directory entries, can be null
118 * @param directory the directory to scan 120 * @param directory the directory to scan
119 * @param callback The callback which will be called for each entry 121 * @param callback The callback which will be called for each entry
122 * @param recursion Number of children directories to read before giving up
120 * @return whether scanning the directory succeeded 123 * @return whether scanning the directory succeeded
121 */ 124 */
122bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback); 125bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback, unsigned int recursion = 0);
123 126
124/** 127/**
125 * Scans the directory tree, storing the results. 128 * Scans the directory tree, storing the results.
126 * @param directory the parent directory to start scanning from 129 * @param directory the parent directory to start scanning from
127 * @param parent_entry FSTEntry where the filesystem tree results will be stored. 130 * @param parent_entry FSTEntry where the filesystem tree results will be stored.
131 * @param recursion Number of children directories to read before giving up.
128 * @return the total number of files/directories found 132 * @return the total number of files/directories found
129 */ 133 */
130unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry); 134unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, unsigned int recursion = 0);
131 135
132// deletes the given directory and anything under it. Returns true on success. 136// deletes the given directory and anything under it. Returns true on success.
133bool DeleteDirRecursively(const std::string &directory); 137bool DeleteDirRecursively(const std::string &directory, unsigned int recursion = 256);
134 138
135// Returns the current directory 139// Returns the current directory
136std::string GetCurrentDir(); 140std::string GetCurrentDir();