From 1a33e2845271b9a46d986f09e051fac88e6e50d7 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Thu, 20 Jun 2024 00:35:46 -0400 Subject: [PATCH] Update Achievement Sort and Progress on RP Whenever a request to update the Rich Presence comes in, typically every ten seconds, the Achievement Progress Widget will update the sort order of the achievements and all of their measured values. --- .../DolphinQt/Achievements/AchievementBox.cpp | 55 ++++++++++--------- .../AchievementProgressWidget.cpp | 16 ++++-- .../Achievements/AchievementsWindow.cpp | 2 +- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/Source/Core/DolphinQt/Achievements/AchievementBox.cpp b/Source/Core/DolphinQt/Achievements/AchievementBox.cpp index edfcf6fdf9..987b92a6a0 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementBox.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementBox.cpp @@ -61,33 +61,36 @@ AchievementBox::AchievementBox(QWidget* parent, rc_client_achievement_t* achieve void AchievementBox::UpdateData() { - std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; - // rc_client guarantees m_achievement will be valid as long as the game is loaded - if (!AchievementManager::GetInstance().IsGameLoaded()) - return; - - const auto& badge = AchievementManager::GetInstance().GetAchievementBadge( - m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED); - std::string_view color = AchievementManager::GRAY; - if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE) - color = AchievementManager::GOLD; - else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE) - color = AchievementManager::BLUE; - QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888); - m_badge->setPixmap( - QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); - m_badge->adjustSize(); - m_badge->setStyleSheet(QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color))); - - if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED) { - m_status->setText( - tr("Unlocked at %1") - .arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString())); - } - else - { - m_status->setText(tr("Locked")); + std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; + // rc_client guarantees m_achievement will be valid as long as the game is loaded + if (!AchievementManager::GetInstance().IsGameLoaded()) + return; + + const auto& badge = AchievementManager::GetInstance().GetAchievementBadge( + m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED); + std::string_view color = AchievementManager::GRAY; + if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE) + color = AchievementManager::GOLD; + else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE) + color = AchievementManager::BLUE; + QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888); + m_badge->setPixmap( + QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + m_badge->adjustSize(); + m_badge->setStyleSheet( + QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color))); + + if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED) + { + m_status->setText( + tr("Unlocked at %1") + .arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString())); + } + else + { + m_status->setText(tr("Locked")); + } } UpdateProgress(); diff --git a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp index 352645c5db..235f37a5d8 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp @@ -51,7 +51,7 @@ void AchievementProgressWidget::UpdateData(bool clean_all) m_common_layout->removeWidget(widget); if (std::strcmp(widget->metaObject()->className(), "QLabel") == 0) { - delete widget; + widget->deleteLater(); delete item; } } @@ -64,22 +64,26 @@ void AchievementProgressWidget::UpdateData(bool clean_all) auto* achievement_list = rc_client_create_achievement_list(client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL, RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS); + if (!achievement_list) + return; for (u32 ix = 0; ix < achievement_list->num_buckets; ix++) { m_common_layout->addWidget(new QLabel(tr(achievement_list->buckets[ix].label))); for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++) { auto* achievement = achievement_list->buckets[ix].achievements[jx]; - auto box_itr = m_achievement_boxes.find(achievement->id); - if (box_itr == m_achievement_boxes.end()) + auto box_itr = m_achievement_boxes.lower_bound(achievement->id); + if (box_itr != m_achievement_boxes.end() && box_itr->first == achievement->id) { - m_achievement_boxes[achievement->id] = std::make_shared(this, achievement); + box_itr->second->UpdateProgress(); + m_common_layout->addWidget(box_itr->second.get()); } else { - box_itr->second->UpdateProgress(); + const auto new_box_itr = m_achievement_boxes.try_emplace( + box_itr, achievement->id, std::make_shared(this, achievement)); + m_common_layout->addWidget(new_box_itr->second.get()); } - m_common_layout->addWidget(m_achievement_boxes[achievement->id].get()); } } rc_client_destroy_achievement_list(achievement_list); diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index b796b9dc3e..eb79896de2 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -89,7 +89,7 @@ void AchievementsWindow::UpdateData(AchievementManager::UpdatedItems updated_ite { m_header_widget->UpdateData(); } - if (updated_items.all_achievements) + if (updated_items.all_achievements || updated_items.rich_presence) m_progress_widget->UpdateData(false); else if (updated_items.achievements.size() > 0) m_progress_widget->UpdateData(updated_items.achievements);