From d2069e888d75abc51fa23e9dd5d43f405e48ce33 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 9 Mar 2024 21:34:20 -0500 Subject: [PATCH] Refactored AchievementProgressWidget to maintain AchievementBox list AchievementProgressWidget maintains in memory a map of AchievementBox pointers so that UpdateData can operate on them individually. UpdateData is overhauled for three options: UpdateData(true) will destroy the entire list and re-create it from scratch as before, to be used if the game or player changes/closes/logs out. UpdateData(false) will loop through the map and call UpdateData on every achievement box, to be used for certain settings changes such as enabling badges or disabling hardcore mode. UpdateData(set) will call UpdateData on only the IDs in the set, to be used when achievements are unlocked. --- .../AchievementProgressWidget.cpp | 59 +++++++++++++------ .../Achievements/AchievementProgressWidget.h | 6 +- .../Achievements/AchievementsWindow.cpp | 2 +- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp index bfa008db5a..548bd5b9c1 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp @@ -27,10 +27,7 @@ AchievementProgressWidget::AchievementProgressWidget(QWidget* parent) : QWidget( m_common_box = new QGroupBox(); m_common_layout = new QVBoxLayout(); - { - std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; - UpdateData(); - } + UpdateData(true); m_common_box->setLayout(m_common_layout); @@ -41,24 +38,48 @@ AchievementProgressWidget::AchievementProgressWidget(QWidget* parent) : QWidget( setLayout(layout); } -void AchievementProgressWidget::UpdateData() +void AchievementProgressWidget::UpdateData(bool clean_all) { - ClearLayoutRecursively(m_common_layout); - - auto& instance = AchievementManager::GetInstance(); - if (!instance.IsGameLoaded()) - return; - - auto* client = instance.GetClient(); - auto* achievement_list = - rc_client_create_achievement_list(client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL, - RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE); - for (u32 ix = 0; ix < achievement_list->num_buckets; ix++) + if (clean_all) { - for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++) + m_achievement_boxes.clear(); + ClearLayoutRecursively(m_common_layout); + + auto& instance = AchievementManager::GetInstance(); + if (!instance.IsGameLoaded()) + return; + auto* client = instance.GetClient(); + auto* achievement_list = rc_client_create_achievement_list( + client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL, + RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE); + for (u32 ix = 0; ix < achievement_list->num_buckets; ix++) { - m_common_layout->addWidget( - new AchievementBox(this, achievement_list->buckets[ix].achievements[jx])); + for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++) + { + auto* achievement = achievement_list->buckets[ix].achievements[jx]; + m_achievement_boxes[achievement->id] = std::make_shared(this, achievement); + m_common_layout->addWidget(m_achievement_boxes[achievement->id].get()); + } + } + rc_client_destroy_achievement_list(achievement_list); + } + else + { + for (auto box : m_achievement_boxes) + { + box.second->UpdateData(); + } + } +} + +void AchievementProgressWidget::UpdateData( + const std::set& update_ids) +{ + for (auto& [id, box] : m_achievement_boxes) + { + if (update_ids.contains(id)) + { + box->UpdateData(); } } } diff --git a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h index 32d2754fd3..9aa2f8cfe7 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h +++ b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h @@ -7,7 +7,9 @@ #include #include "Common/CommonTypes.h" +#include "Core/AchievementManager.h" +class AchievementBox; class QCheckBox; class QGroupBox; class QLineEdit; @@ -21,11 +23,13 @@ class AchievementProgressWidget final : public QWidget Q_OBJECT public: explicit AchievementProgressWidget(QWidget* parent); - void UpdateData(); + void UpdateData(bool clean_all); + void UpdateData(const std::set& update_ids); private: QGroupBox* m_common_box; QVBoxLayout* m_common_layout; + std::map> m_achievement_boxes; }; #endif // USE_RETRO_ACHIEVEMENTS diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index f8dcda0a25..a95e844e29 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -81,7 +81,7 @@ void AchievementsWindow::UpdateData() m_header_widget->UpdateData(); m_header_widget->setVisible(instance.HasAPIToken()); m_settings_widget->UpdateData(); - m_progress_widget->UpdateData(); + m_progress_widget->UpdateData(true); m_tab_widget->setTabVisible(1, is_game_loaded); m_leaderboard_widget->UpdateData(); m_tab_widget->setTabVisible(2, is_game_loaded);