Core: Make AddOnStateChangedCallback use HookableEvent.

This commit is contained in:
Jordan Woyak 2025-11-09 16:34:50 -06:00
parent fdf822f430
commit a97627e736
7 changed files with 15 additions and 37 deletions

View File

@ -99,7 +99,7 @@ static bool s_wants_determinism;
// Declarations and definitions // Declarations and definitions
static std::thread s_emu_thread; static std::thread s_emu_thread;
static std::vector<StateChangedCallbackFunc> s_on_state_changed_callbacks; static Common::HookableEvent<Core::State> s_state_changed_event;
static bool s_is_throttler_temp_disabled = false; static bool s_is_throttler_temp_disabled = false;
static bool s_frame_step = false; static bool s_frame_step = false;
@ -930,38 +930,14 @@ void Shutdown(Core::System& system)
HostDispatchJobs(system); HostDispatchJobs(system);
} }
int AddOnStateChangedCallback(StateChangedCallbackFunc callback) Common::EventHook AddOnStateChangedCallback(StateChangedCallbackFunc callback)
{ {
for (size_t i = 0; i < s_on_state_changed_callbacks.size(); ++i) return s_state_changed_event.Register(std::move(callback));
{
if (!s_on_state_changed_callbacks[i])
{
s_on_state_changed_callbacks[i] = std::move(callback);
return int(i);
}
}
s_on_state_changed_callbacks.emplace_back(std::move(callback));
return int(s_on_state_changed_callbacks.size()) - 1;
}
bool RemoveOnStateChangedCallback(int* handle)
{
if (handle && *handle >= 0 && s_on_state_changed_callbacks.size() > static_cast<size_t>(*handle))
{
s_on_state_changed_callbacks[*handle] = StateChangedCallbackFunc();
*handle = -1;
return true;
}
return false;
} }
void NotifyStateChanged(Core::State state) void NotifyStateChanged(Core::State state)
{ {
for (const StateChangedCallbackFunc& on_state_changed_callback : s_on_state_changed_callbacks) s_state_changed_event.Trigger(state);
{
if (on_state_changed_callback)
on_state_changed_callback(state);
}
g_perf_metrics.OnEmulationStateChanged(state); g_perf_metrics.OnEmulationStateChanged(state);
} }

View File

@ -16,6 +16,7 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Functional.h" #include "Common/Functional.h"
#include "Common/HookableEvent.h"
struct BootParameters; struct BootParameters;
struct WindowSystemInfo; struct WindowSystemInfo;
@ -165,10 +166,8 @@ void RunOnCPUThread(Core::System& system, Common::MoveOnlyFunction<void()> funct
// for calling back into UI code without introducing a dependency on it in core // for calling back into UI code without introducing a dependency on it in core
using StateChangedCallbackFunc = std::function<void(Core::State)>; using StateChangedCallbackFunc = std::function<void(Core::State)>;
// Returns a handle
int AddOnStateChangedCallback(StateChangedCallbackFunc callback); [[nodiscard]] Common::EventHook AddOnStateChangedCallback(StateChangedCallbackFunc callback);
// Also invalidates the handle
bool RemoveOnStateChangedCallback(int* handle);
void NotifyStateChanged(Core::State state); void NotifyStateChanged(Core::State state);
// Run on the Host thread when the factors change. [NOT THREADSAFE] // Run on the Host thread when the factors change. [NOT THREADSAFE]

View File

@ -106,7 +106,7 @@ void CoreTimingManager::Init()
m_last_oc_factor = m_config_oc_factor; m_last_oc_factor = m_config_oc_factor;
m_globals.last_OC_factor_inverted = m_config_oc_inv_factor; m_globals.last_OC_factor_inverted = m_config_oc_inv_factor;
m_on_state_changed_handle = Core::AddOnStateChangedCallback([this](Core::State state) { m_core_state_changed_hook = Core::AddOnStateChangedCallback([this](Core::State state) {
if (state == Core::State::Running) if (state == Core::State::Running)
{ {
// We don't want Throttle to attempt catch-up for all the time lost while paused. // We don't want Throttle to attempt catch-up for all the time lost while paused.
@ -117,7 +117,7 @@ void CoreTimingManager::Init()
void CoreTimingManager::Shutdown() void CoreTimingManager::Shutdown()
{ {
Core::RemoveOnStateChangedCallback(&m_on_state_changed_handle); m_core_state_changed_hook.reset();
std::lock_guard lk(m_ts_write_lock); std::lock_guard lk(m_ts_write_lock);
MoveEvents(); MoveEvents();

View File

@ -23,6 +23,7 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/HookableEvent.h"
#include "Common/SPSCQueue.h" #include "Common/SPSCQueue.h"
#include "Common/Timer.h" #include "Common/Timer.h"
#include "Core/CPUThreadConfigCallback.h" #include "Core/CPUThreadConfigCallback.h"
@ -230,7 +231,7 @@ private:
Common::PrecisionTimer m_precision_cpu_timer; Common::PrecisionTimer m_precision_cpu_timer;
Common::PrecisionTimer m_precision_gpu_timer; Common::PrecisionTimer m_precision_gpu_timer;
int m_on_state_changed_handle; Common::EventHook m_core_state_changed_hook;
}; };
} // namespace CoreTiming } // namespace CoreTiming

View File

@ -288,7 +288,7 @@ int main(const int argc, char* argv[])
return 1; return 1;
} }
Core::AddOnStateChangedCallback([](const Core::State state) { auto core_state_changed_hook = Core::AddOnStateChangedCallback([](const Core::State state) {
if (state == Core::State::Uninitialized) if (state == Core::State::Uninitialized)
s_platform->Stop(); s_platform->Stop();
}); });

View File

@ -50,7 +50,7 @@ static std::unique_ptr<QPalette> s_default_palette;
Settings::Settings() Settings::Settings()
{ {
qRegisterMetaType<Core::State>(); qRegisterMetaType<Core::State>();
Core::AddOnStateChangedCallback([this](Core::State new_state) { m_core_state_changed_hook = Core::AddOnStateChangedCallback([this](Core::State new_state) {
QueueOnObject(this, [this, new_state] { QueueOnObject(this, [this, new_state] {
// Avoid signal spam while continuously frame stepping. Will still send a signal for the first // Avoid signal spam while continuously frame stepping. Will still send a signal for the first
// and last framestep. // and last framestep.

View File

@ -236,6 +236,8 @@ private:
std::shared_ptr<NetPlay::NetPlayServer> m_server; std::shared_ptr<NetPlay::NetPlayServer> m_server;
Common::EventHook m_hotplug_event_hook; Common::EventHook m_hotplug_event_hook;
Config::ConfigChangedCallbackID m_config_changed_callback_id; Config::ConfigChangedCallbackID m_config_changed_callback_id;
Common::EventHook m_core_state_changed_hook;
}; };
Q_DECLARE_METATYPE(Core::State); Q_DECLARE_METATYPE(Core::State);