Achievements: Cache user badge path

This commit is contained in:
Stenzek
2025-10-18 18:33:24 +10:00
parent 2bc387fe33
commit ba28a3fb3c
3 changed files with 39 additions and 59 deletions

View File

@@ -168,7 +168,7 @@ static void EnableHardcodeMode(bool display_message, bool display_game_summary);
static void OnHardcoreModeChanged(bool enabled, bool display_message, bool display_game_summary);
static bool IsRAIntegrationInitializing();
static void FinishInitialize();
static void FinishLogin(const rc_client_t* client);
static void FinishLogin();
static void ShowLoginNotification();
static bool IdentifyGame(CDImage* image);
static bool IdentifyCurrentGame();
@@ -276,6 +276,8 @@ struct State
std::recursive_mutex mutex; // large
std::string user_badge_path;
std::string rich_presence_string;
Timer::Value rich_presence_poll_time = 0;
@@ -2080,7 +2082,9 @@ void Achievements::ClientLoginWithPasswordCallback(int result, const char* error
Host::SetBaseStringSettingValue("Cheevos", "LoginTimestamp", fmt::format("{}", std::time(nullptr)).c_str());
Host::CommitBaseSettingChanges();
FinishLogin(client);
// Will be using temporary client if achievements are not enabled.
if (client == s_state.client)
FinishLogin();
}
void Achievements::ClientLoginWithTokenCallback(int result, const char* error_message, rc_client_t* client,
@@ -2113,33 +2117,33 @@ void Achievements::ClientLoginWithTokenCallback(int result, const char* error_me
return;
}
FinishLogin(client);
// Should be active here.
DebugAssert(client == s_state.client);
FinishLogin();
}
void Achievements::FinishLogin(const rc_client_t* client)
void Achievements::FinishLogin()
{
const rc_client_user_t* user = rc_client_get_user_info(client);
const rc_client_user_t* const user = rc_client_get_user_info(s_state.client);
if (!user)
return;
s_state.user_badge_path = GetLocalImagePath(user->username, RC_IMAGE_TYPE_USER);
if (!s_state.user_badge_path.empty() && !FileSystem::FileExists(s_state.user_badge_path.c_str()))
{
std::string url;
if (IsUsingRAIntegration() || !user->avatar_url)
url = GetImageURL(user->username, RC_IMAGE_TYPE_USER);
else
url = user->avatar_url;
DownloadImage(std::move(url), s_state.user_badge_path);
}
PreloadHashDatabase();
Host::OnAchievementsLoginSuccess(user->username, user->score, user->score_softcore, user->num_unread_messages);
if (System::IsValid())
{
const auto lock = GetLock();
if (s_state.client == client)
Host::RunOnCPUThread(ShowLoginNotification);
}
}
void Achievements::ShowLoginNotification()
{
const rc_client_user_t* user = rc_client_get_user_info(s_state.client);
if (!user)
return;
if (g_settings.achievements_notifications)
{
//: Summary for login notification.
@@ -2147,7 +2151,7 @@ void Achievements::ShowLoginNotification()
user->score, user->score_softcore, user->num_unread_messages);
FullscreenUI::AddNotification("achievements_login", LOGIN_NOTIFICATION_TIME, user->display_name, std::move(summary),
GetLoggedInUserBadgePath());
s_state.user_badge_path);
}
}
@@ -2160,27 +2164,9 @@ const char* Achievements::GetLoggedInUserName()
return user->username;
}
std::string Achievements::GetLoggedInUserBadgePath()
const std::string& Achievements::GetLoggedInUserBadgePath()
{
std::string badge_path;
const rc_client_user_t* user = rc_client_get_user_info(s_state.client);
if (!user) [[unlikely]]
return badge_path;
badge_path = GetLocalImagePath(user->username, RC_IMAGE_TYPE_USER);
if (!badge_path.empty() && !FileSystem::FileExists(badge_path.c_str())) [[unlikely]]
{
std::string url;
if (IsUsingRAIntegration() || !user->avatar_url)
url = GetImageURL(user->username, RC_IMAGE_TYPE_USER);
else
url = user->avatar_url;
DownloadImage(std::move(url), badge_path);
}
return badge_path;
return s_state.user_badge_path;
}
SmallString Achievements::GetLoggedInUserPointsSummary()

View File

@@ -176,7 +176,7 @@ const char* GetLoggedInUserName();
/// Returns the path to the user's profile avatar.
/// Should be called with the lock held.
std::string GetLoggedInUserBadgePath();
const std::string& GetLoggedInUserBadgePath();
/// Returns a summary of the user's points.
/// Should be called with the lock held.

View File

@@ -395,7 +395,6 @@ struct ALIGN_TO_CACHE_LINE WidgetsState
bool initialized = false;
bool pause_menu_was_open = false;
bool was_paused_on_quick_menu_open = false;
std::string achievements_user_badge_path;
// Resources
std::shared_ptr<GPUTexture> app_icon_texture;
@@ -1711,16 +1710,14 @@ void FullscreenUI::DrawLandingTemplate(ImVec2* menu_pos, ImVec2* menu_size)
RenderShadowedTextClipped(heading_font, heading_font_size, heading_font_weight, name_pos, name_pos + name_size,
text_color, username, &name_size);
if (s_state.achievements_user_badge_path.empty()) [[unlikely]]
s_state.achievements_user_badge_path = Achievements::GetLoggedInUserBadgePath();
if (!s_state.achievements_user_badge_path.empty()) [[likely]]
if (const std::string& badge_path = Achievements::GetLoggedInUserBadgePath(); !badge_path.empty())
{
const ImVec2 badge_size = ImVec2(UIStyle.LargeFontSize, UIStyle.LargeFontSize);
const ImVec2 badge_pos =
ImVec2(name_pos.x - badge_size.x - LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING), time_pos.y);
dl->AddImage(reinterpret_cast<ImTextureID>(GetCachedTextureAsync(s_state.achievements_user_badge_path)),
badge_pos, badge_pos + badge_size);
dl->AddImage(reinterpret_cast<ImTextureID>(GetCachedTextureAsync(badge_path)), badge_pos,
badge_pos + badge_size);
}
}
}
@@ -5903,10 +5900,7 @@ void FullscreenUI::DrawAchievementsSettingsHeader(SettingsInterface* bsi, std::u
settings_lock.unlock();
{
const auto lock = Achievements::GetLock();
if (s_state.achievements_user_badge_path.empty()) [[unlikely]]
s_state.achievements_user_badge_path = Achievements::GetLoggedInUserBadgePath();
badge_path = s_state.achievements_user_badge_path;
badge_path = Achievements::GetLoggedInUserBadgePath();
if (badge_path.empty())
badge_path = "images/ra-generic-user.png";
@@ -5939,17 +5933,17 @@ void FullscreenUI::DrawAchievementsSettingsHeader(SettingsInterface* bsi, std::u
score_summary = FSUI_VSTR("To use achievements, please log in with your retroachievements.org account.");
}
}
if (GPUTexture* badge_tex = GetCachedTextureAsync(badge_path))
{
const ImRect badge_rect = CenterImage(ImRect(pos, pos + ImVec2(badge_size, badge_size)), badge_tex);
dl->AddImage(reinterpret_cast<ImTextureID>(GetCachedTextureAsync(badge_path)), badge_rect.Min, badge_rect.Max);
}
pos.x += badge_size + LayoutScale(15.0f);
settings_lock.lock();
}
if (GPUTexture* badge_tex = GetCachedTextureAsync(badge_path))
{
const ImRect badge_rect = CenterImage(ImRect(pos, pos + ImVec2(badge_size, badge_size)), badge_tex);
dl->AddImage(reinterpret_cast<ImTextureID>(GetCachedTextureAsync(badge_path)), badge_rect.Min, badge_rect.Max);
}
pos.x += badge_size + LayoutScale(15.0f);
RenderShadowedTextClipped(dl, UIStyle.Font, UIStyle.LargeFontSize, UIStyle.BoldFontWeight, pos,
pos + ImVec2(max_content_width - pos.x, UIStyle.LargeFontSize),
ImGui::GetColorU32(ImGuiCol_Text), username);