From 4b471f0554146463f3b82eed14ff3922a5584e9f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 3 Aug 2018 11:51:48 -0400 Subject: core: Port core to VfsFilesystem for file access --- src/yuzu/game_list.cpp | 7 ++++--- src/yuzu/game_list.h | 3 ++- src/yuzu/game_list_p.h | 3 ++- src/yuzu/main.cpp | 10 ++++++---- src/yuzu/main.h | 3 +++ 5 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src/yuzu') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 5f47f5a2b..e150a0684 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -197,7 +197,8 @@ void GameList::onFilterCloseClicked() { main_window->filterBarSetChecked(false); } -GameList::GameList(GMainWindow* parent) : QWidget{parent} { +GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) + : QWidget{parent}, vfs(std::move(vfs)) { watcher = new QFileSystemWatcher(this); connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); @@ -341,7 +342,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { emit ShouldCancelWorker(); - GameListWorker* worker = new GameListWorker(dir_path, deep_scan); + GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan); connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating, @@ -436,7 +437,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign if (!is_dir && (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { std::unique_ptr loader = - Loader::GetLoader(std::make_shared(physical_name)); + Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read)); if (!loader || ((loader->GetFileType() == Loader::FileType::Unknown || loader->GetFileType() == Loader::FileType::Error) && !UISettings::values.show_unknown)) diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 3bc14f07f..afe624b32 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -59,7 +59,7 @@ public: QToolButton* button_filter_close = nullptr; }; - explicit GameList(GMainWindow* parent = nullptr); + explicit GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent = nullptr); ~GameList() override; void clearFilter(); @@ -90,6 +90,7 @@ private: void PopupContextMenu(const QPoint& menu_location); void RefreshGameDirectory(); + FileSys::VirtualFilesystem vfs; SearchField* search_field; GMainWindow* main_window = nullptr; QVBoxLayout* layout = nullptr; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index a22025e67..49a3f6181 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -139,7 +139,7 @@ class GameListWorker : public QObject, public QRunnable { Q_OBJECT public: - GameListWorker(QString dir_path, bool deep_scan) + GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan) : dir_path(std::move(dir_path)), deep_scan(deep_scan) {} public slots: @@ -163,6 +163,7 @@ signals: void Finished(QStringList watch_list); private: + FileSys::VirtualFilesystem vfs; QStringList watch_list; QString dir_path; bool deep_scan; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index a6241e63e..f7812a392 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -24,6 +24,7 @@ #include "common/string_util.h" #include "core/core.h" #include "core/crypto/key_manager.h" +#include "core/file_sys/vfs_real.h" #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" #include "core/settings.h" @@ -81,9 +82,9 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) { void GMainWindow::ShowCallouts() {} -const int GMainWindow::max_recent_files_item; - -GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { +GMainWindow::GMainWindow() + : config(new Config()), emu_thread(nullptr), + vfs(std::make_shared()) { debug_context = Tegra::DebugContext::Construct(); @@ -132,7 +133,7 @@ void GMainWindow::InitializeWidgets() { render_window = new GRenderWindow(this, emu_thread.get()); render_window->hide(); - game_list = new GameList(this); + game_list = new GameList(vfs, this); ui.horizontalLayout->addWidget(game_list); // Create status bar @@ -406,6 +407,7 @@ bool GMainWindow::LoadROM(const QString& filename) { } Core::System& system{Core::System::GetInstance()}; + system.SetFilesystem(vfs); system.SetGPUDebugContext(debug_context); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 6e335b8f8..74487c58c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -161,6 +161,9 @@ private: bool emulation_running = false; std::unique_ptr emu_thread; + // FS + FileSys::VirtualFilesystem vfs; + // Debugger panes ProfilerWidget* profilerWidget; MicroProfileDialog* microProfileDialog; -- cgit v1.2.3 From 2b6128fe0b8788318a4bbe1fc55ea14aed2981e4 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 6 Aug 2018 23:21:37 -0400 Subject: file_util: Use enum instead of bool for specifing path behavior --- src/common/file_util.cpp | 8 ++++---- src/common/file_util.h | 7 +++++-- src/core/file_sys/vfs_real.cpp | 44 ++++++++++++++++++++++++++---------------- src/yuzu/game_list_p.h | 2 +- 4 files changed, 37 insertions(+), 24 deletions(-) (limited to 'src/yuzu') diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 190cac6d9..3ce590062 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -884,12 +884,12 @@ std::string_view RemoveTrailingSlash(std::string_view path) { return path; } -std::string SanitizePath(std::string_view path_, bool with_platform_slashes) { +std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { std::string path(path_); - char type1 = '\\'; - char type2 = '/'; + char type1 = directory_separator == DirectorySeparator::BackwardSlash ? '/' : '\\'; + char type2 = directory_separator == DirectorySeparator::BackwardSlash ? '\\' : '/'; - if (with_platform_slashes) { + if (directory_separator == DirectorySeparator::PlatformDefault) { #ifdef _WIN32 type1 = '/'; type2 = '\\'; diff --git a/src/common/file_util.h b/src/common/file_util.h index ca63d7466..2711872ae 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -182,9 +182,12 @@ std::vector SliceVector(const std::vector& vector, size_t first, size_t la return std::vector(vector.begin() + first, vector.begin() + first + last); } +enum class DirectorySeparator { ForwardSlash, BackwardSlash, PlatformDefault }; + // Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' -// if windows and with_platform_slashes is true. -std::string SanitizePath(std::string_view path, bool with_platform_slashes = false); +// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows +std::string SanitizePath(std::string_view path, + DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash); // simple wrapper for cstdlib file functions to // hopefully will make error checking easier diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 21ea35aaf..1b5919737 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -53,7 +53,7 @@ bool RealVfsFilesystem::IsWritable() const { } VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(path)) return VfsEntryType::None; if (FileUtil::IsDirectory(path)) @@ -63,7 +63,7 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { } VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); if (cache.find(path) != cache.end()) { auto weak = cache[path]; if (!weak.expired()) { @@ -82,15 +82,17 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { } VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(path) && !FileUtil::CreateEmptyFile(path)) return nullptr; return OpenFile(path, perms); } VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FileUtil::SanitizePath(old_path_, true); - const auto new_path = FileUtil::SanitizePath(new_path_, true); + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || FileUtil::IsDirectory(old_path) || !FileUtil::Copy(old_path, new_path)) @@ -99,8 +101,10 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_ } VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FileUtil::SanitizePath(old_path_, true); - const auto new_path = FileUtil::SanitizePath(new_path_, true); + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) @@ -119,7 +123,7 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ } bool RealVfsFilesystem::DeleteFile(std::string_view path_) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); if (cache.find(path) != cache.end()) { if (!cache[path].expired()) cache[path].lock()->Close(); @@ -129,13 +133,13 @@ bool RealVfsFilesystem::DeleteFile(std::string_view path_) { } VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); // Cannot use make_shared as RealVfsDirectory constructor is private return std::shared_ptr(new RealVfsDirectory(*this, path, perms)); } VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(path) && !FileUtil::CreateDir(path)) return nullptr; // Cannot use make_shared as RealVfsDirectory constructor is private @@ -144,8 +148,10 @@ VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FileUtil::SanitizePath(old_path_, true); - const auto new_path = FileUtil::SanitizePath(new_path_, true); + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || !FileUtil::IsDirectory(old_path)) return nullptr; @@ -155,8 +161,10 @@ VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_, VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FileUtil::SanitizePath(old_path_, true); - const auto new_path = FileUtil::SanitizePath(new_path_, true); + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) return nullptr; @@ -164,9 +172,11 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, for (auto& kv : cache) { // Path in cache starts with old_path if (kv.first.rfind(old_path, 0) == 0) { - const auto file_old_path = FileUtil::SanitizePath(kv.first, true); + const auto file_old_path = + FileUtil::SanitizePath(kv.first, FileUtil::DirectorySeparator::PlatformDefault); const auto file_new_path = - FileUtil::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), true); + FileUtil::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), + FileUtil::DirectorySeparator::PlatformDefault); auto cached = cache[file_old_path]; if (!cached.expired()) { auto file = cached.lock(); @@ -181,7 +191,7 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, } bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { - const auto path = FileUtil::SanitizePath(path_, true); + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); for (auto& kv : cache) { // Path in cache starts with old_path if (kv.first.rfind(path, 0) == 0) { diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index 49a3f6181..114a0fc7f 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -140,7 +140,7 @@ class GameListWorker : public QObject, public QRunnable { public: GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan) - : dir_path(std::move(dir_path)), deep_scan(deep_scan) {} + : vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan) {} public slots: /// Starts the processing of directory tree information. -- cgit v1.2.3 From 94cf327e776eff934052847346d8415d584b369b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 8 Aug 2018 14:34:06 -0400 Subject: vfs: Fix typo in VfsFilesystem docs --- src/core/file_sys/vfs.h | 2 +- src/yuzu/game_list.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/yuzu') diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index 9c7ef93b8..bf16e7286 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h @@ -31,7 +31,7 @@ enum class VfsEntryType { Directory, }; -// A class represnting an abstract filesystem. A default implementation given the root VirtualDir is +// A class representing an abstract filesystem. A default implementation given the root VirtualDir is // provided for convenience, but if the Vfs implementation has any additional state or // functionality, they will need to override. struct VfsFilesystem : NonCopyable { diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index e150a0684..1c738d2a4 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -15,6 +15,7 @@ #include "common/string_util.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" +#include "core/file_sys/romfs.h" #include "core/file_sys/vfs_real.h" #include "core/loader/loader.h" #include "game_list.h" @@ -415,8 +416,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign bool is_dir = FileUtil::IsDirectory(physical_name); QFileInfo file_info(physical_name.c_str()); if (!is_dir && file_info.suffix().toStdString() == "nca") { - auto nca = std::make_shared( - std::make_shared(physical_name)); + auto nca = + std::make_shared(vfs->OpenFile(physical_name, FileSys::Mode::Read)); if (nca->GetType() == FileSys::NCAContentType::Control) nca_control_map.insert_or_assign(nca->GetTitleId(), nca); } @@ -460,7 +461,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign // Use from metadata pool. if (nca_control_map.find(program_id) != nca_control_map.end()) { const auto nca = nca_control_map[program_id]; - const auto control_dir = nca->GetSubdirectories()[0]; + const auto control_dir = FileSys::ExtractRomFS(nca->GetRomFS()); const auto nacp_file = control_dir->GetFile("control.nacp"); FileSys::NACP nacp(nacp_file); -- cgit v1.2.3 From 668458525ede125509ee27388221247b639f4676 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 8 Aug 2018 21:44:59 -0400 Subject: vfs: Fix documentation --- src/core/file_sys/vfs.h | 4 ++-- src/yuzu/main.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/yuzu') diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index bf16e7286..141a053ce 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h @@ -31,8 +31,8 @@ enum class VfsEntryType { Directory, }; -// A class representing an abstract filesystem. A default implementation given the root VirtualDir is -// provided for convenience, but if the Vfs implementation has any additional state or +// A class representing an abstract filesystem. A default implementation given the root VirtualDir +// is provided for convenience, but if the Vfs implementation has any additional state or // functionality, they will need to override. struct VfsFilesystem : NonCopyable { VfsFilesystem(VirtualDir root); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f7812a392..67e3c6549 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -82,6 +82,8 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) { void GMainWindow::ShowCallouts() {} +const int GMainWindow::max_recent_files_item; + GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr), vfs(std::make_shared()) { -- cgit v1.2.3