mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Merge pull request #13892 from JosJuice/retroachievements-hookableevent
AchievementManager: Use HookableEvent instead of std::function callbacks
This commit is contained in:
commit
5a153c3d41
@ -122,16 +122,6 @@ picojson::value AchievementManager::LoadApprovedList()
|
||||
return temp;
|
||||
}
|
||||
|
||||
void AchievementManager::SetUpdateCallback(UpdateCallback callback)
|
||||
{
|
||||
m_update_callback = std::move(callback);
|
||||
|
||||
if (!m_update_callback)
|
||||
m_update_callback = [](UpdatedItems) {};
|
||||
|
||||
m_update_callback(UpdatedItems{.all = true});
|
||||
}
|
||||
|
||||
void AchievementManager::Login(const std::string& password)
|
||||
{
|
||||
if (!m_client)
|
||||
@ -354,7 +344,7 @@ void AchievementManager::DoFrame()
|
||||
{
|
||||
m_last_rp_time = current_time;
|
||||
rc_client_get_rich_presence_message(m_client, m_rich_presence.data(), RP_SIZE);
|
||||
m_update_callback(UpdatedItems{.rich_presence = true});
|
||||
UpdateEvent::Trigger(UpdatedItems{.rich_presence = true});
|
||||
if (Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED))
|
||||
Discord::UpdateDiscordPresence();
|
||||
}
|
||||
@ -753,7 +743,7 @@ void AchievementManager::CloseGame()
|
||||
INFO_LOG_FMT(ACHIEVEMENTS, "Game closed.");
|
||||
}
|
||||
|
||||
m_update_callback(UpdatedItems{.all = true});
|
||||
UpdateEvent::Trigger(UpdatedItems{.all = true});
|
||||
}
|
||||
|
||||
void AchievementManager::Logout()
|
||||
@ -767,7 +757,7 @@ void AchievementManager::Logout()
|
||||
Config::SetBaseOrCurrent(Config::RA_API_TOKEN, "");
|
||||
}
|
||||
|
||||
m_update_callback(UpdatedItems{.all = true});
|
||||
UpdateEvent::Trigger(UpdatedItems{.all = true});
|
||||
INFO_LOG_FMT(ACHIEVEMENTS, "Logged out from server.");
|
||||
}
|
||||
|
||||
@ -910,7 +900,7 @@ void AchievementManager::LoginCallback(int result, const char* error_message, rc
|
||||
{
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to login {} to RetroAchievements server.",
|
||||
Config::Get(Config::RA_USERNAME));
|
||||
AchievementManager::GetInstance().m_update_callback({.failed_login_code = result});
|
||||
UpdateEvent::Trigger({.failed_login_code = result});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -922,7 +912,7 @@ void AchievementManager::LoginCallback(int result, const char* error_message, rc
|
||||
if (!user)
|
||||
{
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to retrieve user information from client.");
|
||||
AchievementManager::GetInstance().m_update_callback({.failed_login_code = RC_INVALID_STATE});
|
||||
UpdateEvent::Trigger({.failed_login_code = RC_INVALID_STATE});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -941,7 +931,7 @@ void AchievementManager::LoginCallback(int result, const char* error_message, rc
|
||||
INFO_LOG_FMT(ACHIEVEMENTS, "Attempted to login prior user {}; current user is {}.",
|
||||
user->username, Config::Get(Config::RA_USERNAME));
|
||||
rc_client_logout(client);
|
||||
AchievementManager::GetInstance().m_update_callback({.failed_login_code = RC_INVALID_STATE});
|
||||
UpdateEvent::Trigger({.failed_login_code = RC_INVALID_STATE});
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -987,7 +977,7 @@ void AchievementManager::LeaderboardEntriesCallback(int result, const char* erro
|
||||
if (static_cast<int32_t>(ix) == list->user_index)
|
||||
leaderboard.player_index = response_entry.rank;
|
||||
}
|
||||
AchievementManager::GetInstance().m_update_callback({.leaderboards = {*leaderboard_id}});
|
||||
UpdateEvent::Trigger({.leaderboards = {*leaderboard_id}});
|
||||
}
|
||||
|
||||
void AchievementManager::LoadGameCallback(int result, const char* error_message,
|
||||
@ -1033,7 +1023,7 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message,
|
||||
rc_client_set_read_memory_function(instance.m_client, MemoryPeeker);
|
||||
instance.FetchGameBadges();
|
||||
instance.m_system.store(&Core::System::GetInstance(), std::memory_order_release);
|
||||
instance.m_update_callback({.all = true});
|
||||
UpdateEvent::Trigger({.all = true});
|
||||
// Set this to a value that will immediately trigger RP
|
||||
instance.m_last_rp_time = std::chrono::steady_clock::now() - std::chrono::minutes{2};
|
||||
|
||||
@ -1121,8 +1111,7 @@ void AchievementManager::HandleAchievementTriggeredEvent(const rc_client_event_t
|
||||
(rc_client_get_hardcore_enabled(instance.m_client)) ? OSD::Color::YELLOW :
|
||||
OSD::Color::CYAN,
|
||||
&instance.GetAchievementBadge(client_event->achievement->id, false));
|
||||
AchievementManager::GetInstance().m_update_callback(
|
||||
UpdatedItems{.achievements = {client_event->achievement->id}});
|
||||
UpdateEvent::Trigger(UpdatedItems{.achievements = {client_event->achievement->id}});
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
switch (rc_client_raintegration_get_achievement_state(instance.m_client,
|
||||
client_event->achievement->id))
|
||||
@ -1171,8 +1160,7 @@ void AchievementManager::HandleLeaderboardSubmittedEvent(const rc_client_event_t
|
||||
client_event->leaderboard->title),
|
||||
OSD::Duration::VERY_LONG, OSD::Color::YELLOW);
|
||||
AchievementManager::GetInstance().FetchBoardInfo(client_event->leaderboard->id);
|
||||
AchievementManager::GetInstance().m_update_callback(
|
||||
UpdatedItems{.leaderboards = {client_event->leaderboard->id}});
|
||||
UpdateEvent::Trigger(UpdatedItems{.leaderboards = {client_event->leaderboard->id}});
|
||||
}
|
||||
|
||||
void AchievementManager::HandleLeaderboardTrackerUpdateEvent(const rc_client_event_t* client_event)
|
||||
@ -1209,7 +1197,7 @@ void AchievementManager::HandleAchievementChallengeIndicatorShowEvent(
|
||||
const auto [iter, inserted] = instance.m_active_challenges.insert(client_event->achievement->id);
|
||||
if (inserted)
|
||||
instance.m_challenges_updated = true;
|
||||
AchievementManager::GetInstance().m_update_callback(UpdatedItems{.rich_presence = true});
|
||||
UpdateEvent::Trigger(UpdatedItems{.rich_presence = true});
|
||||
}
|
||||
|
||||
void AchievementManager::HandleAchievementChallengeIndicatorHideEvent(
|
||||
@ -1219,7 +1207,7 @@ void AchievementManager::HandleAchievementChallengeIndicatorHideEvent(
|
||||
const auto removed = instance.m_active_challenges.erase(client_event->achievement->id);
|
||||
if (removed > 0)
|
||||
instance.m_challenges_updated = true;
|
||||
AchievementManager::GetInstance().m_update_callback(UpdatedItems{.rich_presence = true});
|
||||
UpdateEvent::Trigger(UpdatedItems{.rich_presence = true});
|
||||
}
|
||||
|
||||
void AchievementManager::HandleAchievementProgressIndicatorShowEvent(
|
||||
@ -1235,8 +1223,7 @@ void AchievementManager::HandleAchievementProgressIndicatorShowEvent(
|
||||
OSD::Duration::SHORT, OSD::Color::GREEN,
|
||||
&instance.GetAchievementBadge(client_event->achievement->id, false));
|
||||
instance.m_last_progress_message = current_time;
|
||||
AchievementManager::GetInstance().m_update_callback(
|
||||
UpdatedItems{.achievements = {client_event->achievement->id}});
|
||||
UpdateEvent::Trigger(UpdatedItems{.achievements = {client_event->achievement->id}});
|
||||
}
|
||||
|
||||
void AchievementManager::HandleGameCompletedEvent(const rc_client_event_t* client_event,
|
||||
@ -1375,7 +1362,7 @@ void AchievementManager::FetchBadge(AchievementManager::Badge* badge, u32 badge_
|
||||
{
|
||||
if (!m_client || !HasAPIToken())
|
||||
{
|
||||
m_update_callback(callback_data);
|
||||
UpdateEvent::Trigger(callback_data);
|
||||
if (m_display_welcome_message && badge_type == RC_IMAGE_TYPE_GAME)
|
||||
DisplayWelcomeMessage();
|
||||
return;
|
||||
@ -1421,7 +1408,7 @@ void AchievementManager::FetchBadge(AchievementManager::Badge* badge, u32 badge_
|
||||
"RetroAchievements connection failed on image request.\n URL: {}",
|
||||
api_request.url);
|
||||
rc_api_destroy_request(&api_request);
|
||||
m_update_callback(callback_data);
|
||||
UpdateEvent::Trigger(callback_data);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1454,7 +1441,7 @@ void AchievementManager::FetchBadge(AchievementManager::Badge* badge, u32 badge_
|
||||
}
|
||||
|
||||
*badge = std::move(tmp_badge);
|
||||
m_update_callback(callback_data);
|
||||
UpdateEvent::Trigger(callback_data);
|
||||
if (badge_type == RC_IMAGE_TYPE_ACHIEVEMENT &&
|
||||
m_active_challenges.contains(*callback_data.achievements.begin()))
|
||||
{
|
||||
@ -1530,7 +1517,7 @@ void AchievementManager::LoadIntegrationCallback(int result, const char* error_m
|
||||
rc_client_raintegration_set_event_handler(instance.m_client, RAIntegrationEventHandler);
|
||||
rc_client_raintegration_set_write_memory_function(instance.m_client, MemoryPoker);
|
||||
rc_client_raintegration_set_get_game_name_function(instance.m_client, GameTitleEstimateHandler);
|
||||
instance.m_dev_menu_callback();
|
||||
DevMenuUpdateEvent::Trigger();
|
||||
// TODO: hook up menu and dll event handlers
|
||||
break;
|
||||
|
||||
@ -1552,12 +1539,11 @@ void AchievementManager::LoadIntegrationCallback(int result, const char* error_m
|
||||
void AchievementManager::RAIntegrationEventHandler(const rc_client_raintegration_event_t* event,
|
||||
rc_client_t* client)
|
||||
{
|
||||
auto& instance = AchievementManager::GetInstance();
|
||||
switch (event->type)
|
||||
{
|
||||
case RC_CLIENT_RAINTEGRATION_EVENT_MENU_CHANGED:
|
||||
case RC_CLIENT_RAINTEGRATION_EVENT_MENUITEM_CHECKED_CHANGED:
|
||||
instance.m_dev_menu_callback();
|
||||
DevMenuUpdateEvent::Trigger();
|
||||
break;
|
||||
case RC_CLIENT_RAINTEGRATION_EVENT_PAUSE:
|
||||
{
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Common/HookableEvent.h"
|
||||
#include "Common/HttpRequest.h"
|
||||
#include "Common/JsonUtil.h"
|
||||
#include "Common/Lazy.h"
|
||||
@ -119,11 +120,10 @@ public:
|
||||
bool rich_presence = false;
|
||||
int failed_login_code = 0;
|
||||
};
|
||||
using UpdateCallback = std::function<void(const UpdatedItems&)>;
|
||||
using UpdateEvent = Common::HookableEvent<"AchievementManagerUpdate", const UpdatedItems&>;
|
||||
|
||||
static AchievementManager& GetInstance();
|
||||
void Init(void* hwnd);
|
||||
void SetUpdateCallback(UpdateCallback callback);
|
||||
void Login(const std::string& password);
|
||||
bool HasAPIToken() const;
|
||||
void LoadGame(const DiscIO::Volume* volume);
|
||||
@ -170,12 +170,9 @@ public:
|
||||
std::vector<std::string> GetActiveLeaderboards() const;
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
using DevMenuUpdateEvent = Common::HookableEvent<"AchievementManagerDevMenuUpdate">;
|
||||
const rc_client_raintegration_menu_t* GetDevelopmentMenu();
|
||||
u32 ActivateDevMenuItem(u32 menu_item_id);
|
||||
void SetDevMenuUpdateCallback(std::function<void(void)> callback)
|
||||
{
|
||||
m_dev_menu_callback = callback;
|
||||
}
|
||||
bool CheckForModifications() { return rc_client_raintegration_has_modifications(m_client); }
|
||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
|
||||
@ -267,7 +264,6 @@ private:
|
||||
rc_client_t* m_client{};
|
||||
std::atomic<Core::System*> m_system{};
|
||||
bool m_is_runtime_initialized = false;
|
||||
UpdateCallback m_update_callback = [](const UpdatedItems&) {};
|
||||
std::unique_ptr<DiscIO::Volume> m_loading_volume;
|
||||
Config::ConfigChangedCallbackID m_config_changed_callback_id;
|
||||
Badge m_default_player_badge;
|
||||
@ -294,7 +290,6 @@ private:
|
||||
|
||||
bool m_dll_found = false;
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
std::function<void(void)> m_dev_menu_callback;
|
||||
std::vector<u8> m_cloned_memory;
|
||||
std::recursive_mutex m_memory_lock;
|
||||
std::string m_title_estimate;
|
||||
|
||||
@ -30,12 +30,16 @@ AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent)
|
||||
|
||||
CreateMainLayout();
|
||||
ConnectWidgets();
|
||||
AchievementManager::GetInstance().SetUpdateCallback(
|
||||
|
||||
m_event_hook = AchievementManager::UpdateEvent::Register(
|
||||
[this](AchievementManager::UpdatedItems updated_items) {
|
||||
QueueOnObject(this, [this, updated_items = std::move(updated_items)] {
|
||||
AchievementsWindow::UpdateData(std::move(updated_items));
|
||||
});
|
||||
});
|
||||
},
|
||||
"AchievementsWindow");
|
||||
UpdateData(AchievementManager::UpdatedItems{.all = true});
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
||||
[this] { m_settings_widget->UpdateData(RC_OK); });
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include <QDialog>
|
||||
|
||||
#include "Common/HookableEvent.h"
|
||||
#include "Core/AchievementManager.h"
|
||||
|
||||
class AchievementHeaderWidget;
|
||||
@ -35,6 +36,8 @@ private:
|
||||
AchievementProgressWidget* m_progress_widget;
|
||||
AchievementLeaderboardWidget* m_leaderboard_widget;
|
||||
QDialogButtonBox* m_button_box;
|
||||
|
||||
Common::EventHook m_event_hook;
|
||||
};
|
||||
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
@ -294,8 +294,8 @@ void MenuBar::AddToolsMenu()
|
||||
tools_menu->addAction(tr("Achievements"), this, [this] { emit ShowAchievementsWindow(); });
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
m_achievements_dev_menu = tools_menu->addMenu(tr("RetroAchievements Development"));
|
||||
AchievementManager::GetInstance().SetDevMenuUpdateCallback(
|
||||
[this] { QueueOnObject(this, [this] { this->UpdateAchievementDevelopmentMenu(); }); });
|
||||
m_raintegration_event_hook = AchievementManager::DevMenuUpdateEvent::Register(
|
||||
[this] { QueueOnObject(this, [this] { UpdateAchievementDevelopmentMenu(); }); }, "MenuBar");
|
||||
m_achievements_dev_menu->menuAction()->setVisible(false);
|
||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
tools_menu->addSeparator();
|
||||
|
||||
@ -12,6 +12,9 @@
|
||||
#include <QPointer>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
#include "Common/HookableEvent.h"
|
||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
|
||||
class QMenu;
|
||||
class ParallelProgressDialog;
|
||||
@ -299,4 +302,8 @@ private:
|
||||
QAction* m_jit_register_cache_off;
|
||||
|
||||
bool m_game_selected = false;
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
Common::EventHook m_raintegration_event_hook;
|
||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user