RetroAchievements: Delay calling LoadApprovedList

0c14b0c8a7 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.
This commit is contained in:
JosJuice 2024-07-08 18:13:52 +02:00
parent 01a2cf8db9
commit f59678842b
2 changed files with 12 additions and 10 deletions

View File

@ -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<PatchEngine::Patch>& 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<PatchEngine::Patch>&
}
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);

View File

@ -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<DiscIO::Volume> 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<picojson::value> m_ini_root{LoadApprovedList};
std::string m_game_ini_id;
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;