From f59678842b9614969be0813e54d25f6c35e0de63 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 8 Jul 2024 18:13:52 +0200 Subject: [PATCH] RetroAchievements: Delay calling LoadApprovedList 0c14b0c8a70799072ddccb648006914af7c62855 made Dolphin load a file from the Sys folder the first time AchievementManager::GetInstance() is called. Because Android calls AchievementManager::GetInstance() from setBackgroundExecutionAllowedNative, this had two negative consequences on Android: 1. The first time setBackgroundExecutionAllowedNative gets called is often before directory initialization is done. Getting the path of the Sys folder before directory initialization is done causes a crash. 2. setBackgroundExecutionAllowedNative is called from the GUI thread, and we don't want file I/O on the GUI thread for performance reasons. This change makes us load the data from the Sys folder the first time the data is needed instead. This also saves us from having to load the data at all when hardcore mode is inactive. --- Source/Core/Core/AchievementManager.cpp | 15 ++++++++------- Source/Core/Core/AchievementManager.h | 7 ++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index b5eec09d47..d4ee8a0add 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -72,7 +72,7 @@ void AchievementManager::Init() } } -void AchievementManager::LoadApprovedList() +picojson::value AchievementManager::LoadApprovedList() { picojson::value temp; std::string error; @@ -82,7 +82,7 @@ void AchievementManager::LoadApprovedList() WARN_LOG_FMT(ACHIEVEMENTS, "Failed to load approved game settings list {}", APPROVED_LIST_FILENAME); WARN_LOG_FMT(ACHIEVEMENTS, "Error: {}", error); - return; + return {}; } auto context = Common::SHA1::CreateContext(); context->Update(temp.serialize()); @@ -94,10 +94,9 @@ void AchievementManager::LoadApprovedList() WARN_LOG_FMT(ACHIEVEMENTS, "Expected hash {}, found hash {}", Common::SHA1::DigestToString(APPROVED_LIST_HASH), Common::SHA1::DigestToString(digest)); - return; + return {}; } - std::lock_guard lg{m_lock}; - m_ini_root = std::move(temp); + return temp; } void AchievementManager::SetUpdateCallback(UpdateCallback callback) @@ -362,10 +361,12 @@ bool AchievementManager::IsHardcoreModeActive() const void AchievementManager::FilterApprovedPatches(std::vector& patches, const std::string& game_ini_id) const { + std::lock_guard lg{m_lock}; + if (!IsHardcoreModeActive()) return; - if (!m_ini_root.contains(game_ini_id)) + if (!m_ini_root->contains(game_ini_id)) patches.clear(); auto patch_itr = patches.begin(); while (patch_itr != patches.end()) @@ -384,7 +385,7 @@ void AchievementManager::FilterApprovedPatches(std::vector& } auto digest = context->Finish(); - bool verified = m_ini_root.get(game_ini_id).contains(Common::SHA1::DigestToString(digest)); + bool verified = m_ini_root->get(game_ini_id).contains(Common::SHA1::DigestToString(digest)); if (!verified) { patch_itr = patches.erase(patch_itr); diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 66f4398441..6bc9e74a7a 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -29,6 +29,7 @@ #include "Common/Event.h" #include "Common/HttpRequest.h" #include "Common/JsonUtil.h" +#include "Common/Lazy.h" #include "Common/WorkQueueThread.h" #include "DiscIO/Volume.h" #include "VideoCommon/Assets/CustomTextureData.h" @@ -146,7 +147,7 @@ public: void Shutdown(); private: - AchievementManager() { LoadApprovedList(); }; + AchievementManager() = default; struct FilereaderState { @@ -154,7 +155,7 @@ private: std::unique_ptr volume; }; - void LoadApprovedList(); + static picojson::value LoadApprovedList(); static void* FilereaderOpenByFilepath(const char* path_utf8); static void* FilereaderOpenByVolume(const char* path_utf8); @@ -227,7 +228,7 @@ private: std::chrono::steady_clock::time_point m_last_rp_time = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_last_progress_message = std::chrono::steady_clock::now(); - picojson::value m_ini_root; + Common::Lazy m_ini_root{LoadApprovedList}; std::string m_game_ini_id; std::unordered_map m_leaderboard_map;