Add active leaderboard tracker to achievement manager

The active leaderboard data (leaderboards currently being attempted, which get displayed on screen) is now tracked. When a leaderboard is started its value is added to a vector (sorted by start frame). There are a separate set of client events specifically to handle leaderboard trackers, that are used to populate and manage this vector. The top portion of this vector (by RetroAchievement standards, the first four items) is exposed to be displayed on screen.
This commit is contained in:
LillyJadeKatrin 2024-02-24 12:00:09 -05:00
parent eee77ec6b7
commit 6f3a608e92
2 changed files with 53 additions and 0 deletions

View File

@ -402,6 +402,16 @@ const AchievementManager::NamedIconMap& AchievementManager::GetChallengeIcons()
return m_active_challenges;
}
std::vector<std::string> AchievementManager::GetActiveLeaderboards() const
{
std::vector<std::string> display_values;
for (u32 ix = 0; ix < MAX_DISPLAYED_LBOARDS && ix < m_active_leaderboards.size(); ix++)
{
display_values.push_back(std::string(m_active_leaderboards[ix].display));
}
return display_values;
}
void AchievementManager::CloseGame()
{
{
@ -409,6 +419,7 @@ void AchievementManager::CloseGame()
if (rc_client_get_game_info(m_client))
{
m_active_challenges.clear();
m_active_leaderboards.clear();
m_game_badge.name.clear();
m_unlocked_badges.clear();
m_locked_badges.clear();
@ -827,6 +838,33 @@ void AchievementManager::HandleLeaderboardSubmittedEvent(const rc_client_event_t
OSD::Duration::VERY_LONG, OSD::Color::YELLOW);
}
void AchievementManager::HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t* client_event)
{
auto& active_leaderboards = AchievementManager::GetInstance().m_active_leaderboards;
for (auto& leaderboard : active_leaderboards)
{
if (leaderboard.id == client_event->leaderboard_tracker->id)
{
strncpy(leaderboard.display, client_event->leaderboard_tracker->display,
RC_CLIENT_LEADERBOARD_DISPLAY_SIZE);
}
}
}
void AchievementManager::HandleLeaderboardTrackerShowEvent(const rc_client_event_t* client_event)
{
AchievementManager::GetInstance().m_active_leaderboards.push_back(
*client_event->leaderboard_tracker);
}
void AchievementManager::HandleLeaderboardTrackerHideEvent(const rc_client_event_t* client_event)
{
auto& active_leaderboards = AchievementManager::GetInstance().m_active_leaderboards;
std::erase_if(active_leaderboards, [client_event](const auto& leaderboard) {
return leaderboard.id == client_event->leaderboard_tracker->id;
});
}
// Every RetroAchievements API call, with only a partial exception for fetch_image, follows
// the same design pattern (here, X is the name of the call):
// Create a specific rc_api_X_request_t struct and populate with the necessary values
@ -1023,6 +1061,15 @@ void AchievementManager::EventHandlerV2(const rc_client_event_t* event, rc_clien
case RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED:
HandleLeaderboardSubmittedEvent(event);
break;
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE:
HandleLeaderboardTrackerUpdateEvent(event);
break;
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW:
HandleLeaderboardTrackerShowEvent(event);
break;
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE:
HandleLeaderboardTrackerHideEvent(event);
break;
default:
INFO_LOG_FMT(ACHIEVEMENTS, "Event triggered of unhandled type {}", event->type);
break;

View File

@ -73,6 +73,7 @@ public:
using RichPresence = std::array<char, RP_SIZE>;
using Badge = std::vector<u8>;
using NamedIconMap = std::map<std::string, std::unique_ptr<OSD::Icon>, std::less<>>;
static constexpr size_t MAX_DISPLAYED_LBOARDS = 4;
struct BadgeStatus
{
@ -146,6 +147,7 @@ public:
bool IsDisabled() const { return m_disabled; };
void SetDisabled(bool disabled);
const NamedIconMap& GetChallengeIcons() const;
std::vector<std::string> GetActiveLeaderboards() const;
void CloseGame();
void Logout();
@ -190,6 +192,9 @@ private:
static void HandleLeaderboardStartedEvent(const rc_client_event_t* client_event);
static void HandleLeaderboardFailedEvent(const rc_client_event_t* client_event);
static void HandleLeaderboardSubmittedEvent(const rc_client_event_t* client_event);
static void HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t* client_event);
static void HandleLeaderboardTrackerShowEvent(const rc_client_event_t* client_event);
static void HandleLeaderboardTrackerHideEvent(const rc_client_event_t* client_event);
template <typename RcRequest, typename RcResponse>
ResponseType Request(RcRequest rc_request, RcResponse* rc_response,
@ -224,6 +229,7 @@ private:
std::unordered_map<AchievementId, UnlockStatus> m_unlock_map;
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;
NamedIconMap m_active_challenges;
std::vector<rc_client_leaderboard_tracker_t> m_active_leaderboards;
Common::WorkQueueThread<std::function<void()>> m_queue;
Common::WorkQueueThread<std::function<void()>> m_image_queue;