Merge pull request #12855 from LillyJadeKatrin/retroachievements-challenge-refactor

Refactored Challenge Icons to handle icon updates
This commit is contained in:
Admiral H. Curtiss 2024-06-15 16:24:24 +02:00 committed by GitHub
commit f71d6498d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 36 deletions

View File

@ -338,7 +338,18 @@ AchievementManager::RichPresence AchievementManager::GetRichPresence() const
return m_rich_presence; return m_rich_presence;
} }
const AchievementManager::NamedBadgeMap& AchievementManager::GetChallengeIcons() const const bool AchievementManager::AreChallengesUpdated() const
{
return m_challenges_updated;
}
void AchievementManager::ResetChallengesUpdated()
{
m_challenges_updated = false;
}
const std::unordered_set<AchievementManager::AchievementId>&
AchievementManager::GetActiveChallenges() const
{ {
return m_active_challenges; return m_active_challenges;
} }
@ -802,15 +813,18 @@ void AchievementManager::HandleAchievementChallengeIndicatorShowEvent(
const rc_client_event_t* client_event) const rc_client_event_t* client_event)
{ {
auto& instance = AchievementManager::GetInstance(); auto& instance = AchievementManager::GetInstance();
instance.m_active_challenges[client_event->achievement->badge_name] = const auto [iter, inserted] = instance.m_active_challenges.insert(client_event->achievement->id);
&AchievementManager::GetInstance().GetAchievementBadge(client_event->achievement->id, false); if (inserted)
instance.m_challenges_updated = true;
} }
void AchievementManager::HandleAchievementChallengeIndicatorHideEvent( void AchievementManager::HandleAchievementChallengeIndicatorHideEvent(
const rc_client_event_t* client_event) const rc_client_event_t* client_event)
{ {
AchievementManager::GetInstance().m_active_challenges.erase( auto& instance = AchievementManager::GetInstance();
client_event->achievement->badge_name); const auto removed = instance.m_active_challenges.erase(client_event->achievement->id);
if (removed > 0)
instance.m_challenges_updated = true;
} }
void AchievementManager::HandleAchievementProgressIndicatorShowEvent( void AchievementManager::HandleAchievementProgressIndicatorShowEvent(
@ -981,6 +995,11 @@ void AchievementManager::FetchBadge(AchievementManager::Badge* badge, u32 badge_
} }
m_update_callback(callback_data); m_update_callback(callback_data);
if (badge_type == RC_IMAGE_TYPE_ACHIEVEMENT &&
m_active_challenges.contains(*callback_data.achievements.begin()))
{
m_challenges_updated = true;
}
}); });
} }

View File

@ -16,6 +16,7 @@
#include <string_view> #include <string_view>
#include <thread> #include <thread>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include <rcheevos/include/rc_api_runtime.h> #include <rcheevos/include/rc_api_runtime.h>
@ -50,7 +51,6 @@ public:
static constexpr size_t RP_SIZE = 256; static constexpr size_t RP_SIZE = 256;
using RichPresence = std::array<char, RP_SIZE>; using RichPresence = std::array<char, RP_SIZE>;
using Badge = VideoCommon::CustomTextureData::ArraySlice::Level; using Badge = VideoCommon::CustomTextureData::ArraySlice::Level;
using NamedBadgeMap = std::unordered_map<std::string, const Badge*>;
static constexpr size_t MAX_DISPLAYED_LBOARDS = 4; static constexpr size_t MAX_DISPLAYED_LBOARDS = 4;
static constexpr std::string_view DEFAULT_PLAYER_BADGE_FILENAME = "achievements_player.png"; static constexpr std::string_view DEFAULT_PLAYER_BADGE_FILENAME = "achievements_player.png";
@ -116,7 +116,9 @@ public:
const Badge& GetAchievementBadge(AchievementId id, bool locked) const; const Badge& GetAchievementBadge(AchievementId id, bool locked) const;
const LeaderboardStatus* GetLeaderboardInfo(AchievementId leaderboard_id); const LeaderboardStatus* GetLeaderboardInfo(AchievementId leaderboard_id);
RichPresence GetRichPresence() const; RichPresence GetRichPresence() const;
const NamedBadgeMap& GetChallengeIcons() const; const bool AreChallengesUpdated() const;
void ResetChallengesUpdated();
const std::unordered_set<AchievementId>& GetActiveChallenges() const;
std::vector<std::string> GetActiveLeaderboards() const; std::vector<std::string> GetActiveLeaderboards() const;
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
@ -204,7 +206,8 @@ private:
std::chrono::steady_clock::time_point m_last_progress_message = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_last_progress_message = std::chrono::steady_clock::now();
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map; std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;
NamedBadgeMap m_active_challenges; bool m_challenges_updated = false;
std::unordered_set<AchievementId> m_active_challenges;
std::vector<rc_client_leaderboard_tracker_t> m_active_leaderboards; std::vector<rc_client_leaderboard_tracker_t> m_active_leaderboards;
Common::WorkQueueThread<std::function<void()>> m_queue; Common::WorkQueueThread<std::function<void()>> m_queue;

View File

@ -334,11 +334,28 @@ void OnScreenUI::DrawDebugText()
void OnScreenUI::DrawChallengesAndLeaderboards() void OnScreenUI::DrawChallengesAndLeaderboards()
{ {
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; auto& instance = AchievementManager::GetInstance();
const auto& challenge_icons = AchievementManager::GetInstance().GetChallengeIcons(); std::lock_guard lg{instance.GetLock()};
const auto& leaderboard_progress = AchievementManager::GetInstance().GetActiveLeaderboards(); if (instance.AreChallengesUpdated())
{
instance.ResetChallengesUpdated();
const auto& challenges = instance.GetActiveChallenges();
m_challenge_texture_map.clear();
for (const auto& name : challenges)
{
const auto& icon = instance.GetAchievementBadge(name, false);
const u32 width = icon.width;
const u32 height = icon.height;
TextureConfig tex_config(width, height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0,
AbstractTextureType::Texture_2DArray);
auto res = m_challenge_texture_map.insert_or_assign(name, g_gfx->CreateTexture(tex_config));
res.first->second->Load(0, width, height, width, icon.data.data(),
sizeof(u32) * width * height);
}
}
float leaderboard_y = ImGui::GetIO().DisplaySize.y; float leaderboard_y = ImGui::GetIO().DisplaySize.y;
if (!challenge_icons.empty()) if (!m_challenge_texture_map.empty())
{ {
ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y), 0, ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y), 0,
ImVec2(1.0, 1.0)); ImVec2(1.0, 1.0));
@ -349,37 +366,17 @@ void OnScreenUI::DrawChallengesAndLeaderboards()
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing)) ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
{ {
for (const auto& [name, icon] : challenge_icons)
{
if (m_challenge_texture_map.find(name) != m_challenge_texture_map.end())
continue;
const u32 width = icon->width;
const u32 height = icon->height;
TextureConfig tex_config(width, height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0,
AbstractTextureType::Texture_2DArray);
auto res = m_challenge_texture_map.insert_or_assign(name, g_gfx->CreateTexture(tex_config));
res.first->second->Load(0, width, height, width, icon->data.data(),
sizeof(u32) * width * height);
}
for (auto& [name, texture] : m_challenge_texture_map) for (auto& [name, texture] : m_challenge_texture_map)
{ {
auto icon_itr = challenge_icons.find(name); ImGui::Image(texture.get(), ImVec2(static_cast<float>(texture->GetWidth()),
if (icon_itr == challenge_icons.end()) static_cast<float>(texture->GetHeight())));
{
m_challenge_texture_map.erase(name);
continue;
}
if (texture)
{
ImGui::Image(texture.get(), ImVec2(static_cast<float>(icon_itr->second->width),
static_cast<float>(icon_itr->second->height)));
}
} }
leaderboard_y -= ImGui::GetWindowHeight(); leaderboard_y -= ImGui::GetWindowHeight();
} }
ImGui::End(); ImGui::End();
} }
const auto& leaderboard_progress = instance.GetActiveLeaderboards();
if (!leaderboard_progress.empty()) if (!leaderboard_progress.empty())
{ {
ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x, leaderboard_y), 0, ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x, leaderboard_y), 0,

View File

@ -76,7 +76,7 @@ private:
float m_backbuffer_scale = 1.0; float m_backbuffer_scale = 1.0;
#ifdef USE_RETRO_ACHIEVEMENTS #ifdef USE_RETRO_ACHIEVEMENTS
std::map<std::string, std::unique_ptr<AbstractTexture>, std::less<>> m_challenge_texture_map; std::map<int, std::unique_ptr<AbstractTexture>, std::less<>> m_challenge_texture_map;
#endif // USE_RETRO_ACHIEVEMENTS #endif // USE_RETRO_ACHIEVEMENTS
bool m_ready = false; bool m_ready = false;