From 4963dc1759501a59efaf9baecf0476f10396303c Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 22 Oct 2024 20:41:33 +1000 Subject: [PATCH] Host: Make resource routines fill error object --- src/core/game_database.cpp | 10 ++++++---- src/core/host.cpp | 12 ++++-------- src/duckstation-qt/qthost.cpp | 14 ++++---------- src/duckstation-regtest/regtest_host.cpp | 14 ++++---------- src/util/host.h | 11 ++++++++--- src/util/imgui_fullscreen.cpp | 6 +++--- src/util/imgui_manager.cpp | 22 +++++++++++----------- src/util/postprocessing.cpp | 4 ++-- src/util/postprocessing_shader_fx.cpp | 2 +- 9 files changed, 43 insertions(+), 52 deletions(-) diff --git a/src/core/game_database.cpp b/src/core/game_database.cpp index 7995c41920..e9f98cd754 100644 --- a/src/core/game_database.cpp +++ b/src/core/game_database.cpp @@ -1066,10 +1066,11 @@ void GameDatabase::SetRymlCallbacks() bool GameDatabase::LoadGameDBYaml() { - std::optional> gamedb_data = Host::ReadResourceFile(GAMEDB_YAML_FILENAME, false); + Error error; + std::optional> gamedb_data = Host::ReadResourceFile(GAMEDB_YAML_FILENAME, false, &error); if (!gamedb_data.has_value()) { - ERROR_LOG("Failed to read game database"); + ERROR_LOG("Failed to read game database: {}", error.GetDescription()); return false; } @@ -1384,10 +1385,11 @@ bool GameDatabase::LoadTrackHashes() { Common::Timer load_timer; - std::optional gamedb_data(Host::ReadResourceFileToString(DISCDB_YAML_FILENAME, false)); + Error error; + std::optional gamedb_data(Host::ReadResourceFileToString(DISCDB_YAML_FILENAME, false, &error)); if (!gamedb_data.has_value()) { - ERROR_LOG("Failed to read game database"); + ERROR_LOG("Failed to read disc database: {}", error.GetDescription()); return false; } diff --git a/src/core/host.cpp b/src/core/host.cpp index 1d05b0a814..cfde8bcadd 100644 --- a/src/core/host.cpp +++ b/src/core/host.cpp @@ -44,16 +44,12 @@ SettingsInterface* Host::GetSettingsInterface() return &s_layered_settings_interface; } -std::optional> Host::ReadCompressedResourceFile(std::string_view filename, bool allow_override) +std::optional> Host::ReadCompressedResourceFile(std::string_view filename, bool allow_override, + Error* error) { - std::optional> ret = Host::ReadResourceFile(filename, allow_override); + std::optional> ret = Host::ReadResourceFile(filename, allow_override, error); if (ret.has_value()) - { - Error error; - ret = CompressHelpers::DecompressFile(filename, std::move(ret), std::nullopt, &error); - if (!ret.has_value()) - ERROR_LOG("Failed to decompress '{}': {}", Path::GetFileName(filename), error.GetDescription()); - } + ret = CompressHelpers::DecompressFile(filename, std::move(ret), std::nullopt, error); return ret; } diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index 7a47837360..3eeecb052a 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -2020,22 +2020,16 @@ bool Host::ResourceFileExists(std::string_view filename, bool allow_override) return FileSystem::FileExists(path.c_str()); } -std::optional> Host::ReadResourceFile(std::string_view filename, bool allow_override) +std::optional> Host::ReadResourceFile(std::string_view filename, bool allow_override, Error* error) { const std::string path = QtHost::GetResourcePath(filename, allow_override); - std::optional> ret(FileSystem::ReadBinaryFile(path.c_str())); - if (!ret.has_value()) - ERROR_LOG("Failed to read resource file '{}'", filename); - return ret; + return FileSystem::ReadBinaryFile(path.c_str(), error); } -std::optional Host::ReadResourceFileToString(std::string_view filename, bool allow_override) +std::optional Host::ReadResourceFileToString(std::string_view filename, bool allow_override, Error* error) { const std::string path = QtHost::GetResourcePath(filename, allow_override); - std::optional ret(FileSystem::ReadFileToString(path.c_str())); - if (!ret.has_value()) - ERROR_LOG("Failed to read resource file to string '{}'", filename); - return ret; + return FileSystem::ReadFileToString(path.c_str(), error); } std::optional Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override) diff --git a/src/duckstation-regtest/regtest_host.cpp b/src/duckstation-regtest/regtest_host.cpp index ef25812337..05108c0d7d 100644 --- a/src/duckstation-regtest/regtest_host.cpp +++ b/src/duckstation-regtest/regtest_host.cpp @@ -223,22 +223,16 @@ bool Host::ResourceFileExists(std::string_view filename, bool allow_override) return FileSystem::FileExists(path.c_str()); } -std::optional> Host::ReadResourceFile(std::string_view filename, bool allow_override) +std::optional> Host::ReadResourceFile(std::string_view filename, bool allow_override, Error* error) { const std::string path(Path::Combine(EmuFolders::Resources, filename)); - std::optional> ret(FileSystem::ReadBinaryFile(path.c_str())); - if (!ret.has_value()) - ERROR_LOG("Failed to read resource file '{}'", filename); - return ret; + return FileSystem::ReadBinaryFile(path.c_str(), error); } -std::optional Host::ReadResourceFileToString(std::string_view filename, bool allow_override) +std::optional Host::ReadResourceFileToString(std::string_view filename, bool allow_override, Error* error) { const std::string path(Path::Combine(EmuFolders::Resources, filename)); - std::optional ret(FileSystem::ReadFileToString(path.c_str())); - if (!ret.has_value()) - ERROR_LOG("Failed to read resource file to string '{}'", filename); - return ret; + return FileSystem::ReadFileToString(path.c_str(), error); } std::optional Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override) diff --git a/src/util/host.h b/src/util/host.h index 3503ed22c4..654ae86b3e 100644 --- a/src/util/host.h +++ b/src/util/host.h @@ -12,22 +12,27 @@ #include #include +class Error; + namespace Host { /// Returns true if the specified resource file exists. bool ResourceFileExists(std::string_view filename, bool allow_override); /// Reads a file from the resources directory of the application. /// This may be outside of the "normal" filesystem on platforms such as Mac. -std::optional> ReadResourceFile(std::string_view filename, bool allow_override); +std::optional> ReadResourceFile(std::string_view filename, bool allow_override, + Error* error = nullptr); /// Reads a resource file file from the resources directory as a string. -std::optional ReadResourceFileToString(std::string_view filename, bool allow_override); +std::optional ReadResourceFileToString(std::string_view filename, bool allow_override, + Error* error = nullptr); /// Returns the modified time of a resource. std::optional GetResourceFileTimestamp(std::string_view filename, bool allow_override); /// Reads a potentially-compressed file from the resources directory of the application. -std::optional> ReadCompressedResourceFile(std::string_view filename, bool allow_override); +std::optional> ReadCompressedResourceFile(std::string_view filename, bool allow_override, + Error* error = nullptr); /// Reports a fatal error on the main thread. This does not assume that the main window exists, /// unlike ReportErrorAsync(), and will exit the application after the popup is closed. diff --git a/src/util/imgui_fullscreen.cpp b/src/util/imgui_fullscreen.cpp index e79d0668d1..62d77317d2 100644 --- a/src/util/imgui_fullscreen.cpp +++ b/src/util/imgui_fullscreen.cpp @@ -309,7 +309,7 @@ std::optional ImGuiFullscreen::LoadTextureImage(std::string_view pat if (Path::IsAbsolute(path)) svg_data = FileSystem::ReadBinaryFile(std::string(path).c_str(), &error); else - svg_data = Host::ReadResourceFile(path, true); + svg_data = Host::ReadResourceFile(path, true, &error); if (svg_data.has_value()) { @@ -345,7 +345,7 @@ std::optional ImGuiFullscreen::LoadTextureImage(std::string_view pat } else { - std::optional> data = Host::ReadResourceFile(path, true); + std::optional> data = Host::ReadResourceFile(path, true, &error); if (data.has_value()) { image = RGBA8Image(); @@ -357,7 +357,7 @@ std::optional ImGuiFullscreen::LoadTextureImage(std::string_view pat } else { - ERROR_LOG("Failed to open texture resource '{}'", path); + ERROR_LOG("Failed to open texture resource '{}: {}'", path, error.GetDescription()); } } diff --git a/src/util/imgui_manager.cpp b/src/util/imgui_manager.cpp index 6e35db7e72..7171bd739e 100644 --- a/src/util/imgui_manager.cpp +++ b/src/util/imgui_manager.cpp @@ -69,7 +69,7 @@ static_assert(std::is_same_v); static void UpdateScale(); static void SetStyle(ImGuiStyle& style, float scale); static void SetKeyMap(); -static bool LoadFontData(); +static bool LoadFontData(Error* error); static void ReloadFontDataIfActive(); static bool AddImGuiFonts(bool fullscreen_fonts); static ImFont* AddTextFont(float size, bool full_glyph_range); @@ -229,9 +229,9 @@ void ImGuiManager::SetShowOSDMessages(bool enable) bool ImGuiManager::Initialize(float global_scale, float screen_margin, Error* error) { - if (!LoadFontData()) + if (!LoadFontData(error)) { - Error::SetString(error, "Failed to load font data"); + Error::AddPrefix(error, "Failed to load font data: "); return false; } @@ -558,13 +558,13 @@ void ImGuiManager::SetKeyMap() } } -bool ImGuiManager::LoadFontData() +bool ImGuiManager::LoadFontData(Error* error) { if (s_standard_font_data.empty()) { std::optional> font_data = s_font_path.empty() ? - Host::ReadResourceFile("fonts/Roboto-Regular.ttf", true) : - FileSystem::ReadBinaryFile(s_font_path.c_str()); + Host::ReadResourceFile("fonts/Roboto-Regular.ttf", true, error) : + FileSystem::ReadBinaryFile(s_font_path.c_str(), error); if (!font_data.has_value()) return false; @@ -573,7 +573,7 @@ bool ImGuiManager::LoadFontData() if (s_fixed_font_data.empty()) { - std::optional> font_data = Host::ReadResourceFile("fonts/RobotoMono-Medium.ttf", true); + std::optional> font_data = Host::ReadResourceFile("fonts/RobotoMono-Medium.ttf", true, error); if (!font_data.has_value()) return false; @@ -582,7 +582,7 @@ bool ImGuiManager::LoadFontData() if (s_icon_fa_font_data.empty()) { - std::optional> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf", true); + std::optional> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf", true, error); if (!font_data.has_value()) return false; @@ -591,7 +591,7 @@ bool ImGuiManager::LoadFontData() if (s_icon_pf_font_data.empty()) { - std::optional> font_data = Host::ReadResourceFile("fonts/promptfont.otf", true); + std::optional> font_data = Host::ReadResourceFile("fonts/promptfont.otf", true, error); if (!font_data.has_value()) return false; @@ -601,7 +601,7 @@ bool ImGuiManager::LoadFontData() if (s_emoji_font_data.empty()) { std::optional> font_data = - Host::ReadCompressedResourceFile("fonts/TwitterColorEmoji-SVGinOT.ttf.zst", true); + Host::ReadCompressedResourceFile("fonts/TwitterColorEmoji-SVGinOT.ttf.zst", true, error); if (!font_data.has_value()) return false; @@ -732,7 +732,7 @@ void ImGuiManager::ReloadFontDataIfActive() ImGui::EndFrame(); - if (!LoadFontData()) + if (!LoadFontData(nullptr)) Panic("Failed to load font data"); if (!AddImGuiFonts(HasFullscreenFonts())) diff --git a/src/util/postprocessing.cpp b/src/util/postprocessing.cpp index dda9311624..ed145ca493 100644 --- a/src/util/postprocessing.cpp +++ b/src/util/postprocessing.cpp @@ -725,7 +725,7 @@ std::unique_ptr PostProcessing::TryLoadingShader(const s filename = fmt::format("shaders/reshade" FS_OSPATH_SEPARATOR_STR "Shaders" FS_OSPATH_SEPARATOR_STR "{}.fx", shader_name); - resource_str = Host::ReadResourceFileToString(filename.c_str(), true); + resource_str = Host::ReadResourceFileToString(filename.c_str(), true, error); if (resource_str.has_value()) { std::unique_ptr shader = std::make_unique(); @@ -737,7 +737,7 @@ std::unique_ptr PostProcessing::TryLoadingShader(const s } filename = fmt::format("shaders" FS_OSPATH_SEPARATOR_STR "{}.glsl", shader_name); - resource_str = Host::ReadResourceFileToString(filename.c_str(), true); + resource_str = Host::ReadResourceFileToString(filename.c_str(), true, error); if (resource_str.has_value()) { std::unique_ptr shader = std::make_unique(); diff --git a/src/util/postprocessing_shader_fx.cpp b/src/util/postprocessing_shader_fx.cpp index 9f1ba15288..6486ce9aec 100644 --- a/src/util/postprocessing_shader_fx.cpp +++ b/src/util/postprocessing_shader_fx.cpp @@ -1128,7 +1128,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer { // Might be a base file/resource instead. const std::string resource_name = Path::Combine("shaders/reshade/Textures", source); - if (std::optional> resdata = Host::ReadResourceFile(resource_name.c_str(), true); + if (std::optional> resdata = Host::ReadResourceFile(resource_name.c_str(), true, error); !resdata.has_value() || !image.LoadFromBuffer(resource_name.c_str(), resdata->cspan(), error)) { Error::AddPrefixFmt(error, "Failed to load image '{}' (from '{}'): ", source, image_path);