PerformanceMetrics: Use HookableEvent for state changed callback

Use the normal state changed `HookableEvent` instead of having
`Core::NotifyStateChanged` call `g_perf_metrics.OnEmulationStateChanged`
directly.

The direct call was added in bad78cfed4 to
avoid a crash. At the time state changed callbacks were stored in a
vector, and the crash was caused by `g_perf_metric`'s destructor trying
to remove the callback from the already-destroyed vector.

Later a97627e736 switched state changed
callbacks to use `HookableEvent`, which is specifically designed to
handle the case where a hook outlives its associated event.

Since the workaround is no longer necessary replace it with a standard
`EventHook`.
This commit is contained in:
Dentomologist 2026-03-07 12:33:39 -08:00
parent 49d5299f1e
commit 252ec7452c
3 changed files with 16 additions and 11 deletions

View File

@ -929,10 +929,9 @@ Common::EventHook AddOnStateChangedCallback(StateChangedCallbackFunc callback)
return s_state_changed_event.Register(std::move(callback));
}
void NotifyStateChanged(Core::State state)
void NotifyStateChanged(const Core::State state)
{
s_state_changed_event.Trigger(state);
g_perf_metrics.OnEmulationStateChanged(state);
}
void UpdateWantDeterminism(Core::System& system, bool initial)

View File

@ -8,11 +8,22 @@
#include <imgui.h>
#include <implot.h>
#include "Common/HookableEvent.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/Core.h"
#include "VideoCommon/VideoConfig.h"
PerformanceMetrics g_perf_metrics;
PerformanceMetrics::PerformanceMetrics()
{
const auto invalidate_counters_last_time = [this](Core::State) {
m_fps_counter.InvalidateLastTime();
m_vps_counter.InvalidateLastTime();
};
m_state_change_hook = Core::AddOnStateChangedCallback(invalidate_counters_last_time);
}
void PerformanceMetrics::Reset()
{
m_fps_counter.Reset();
@ -37,12 +48,6 @@ void PerformanceMetrics::CountVBlank()
m_vps_counter.Count();
}
void PerformanceMetrics::OnEmulationStateChanged([[maybe_unused]] Core::State state)
{
m_fps_counter.InvalidateLastTime();
m_vps_counter.InvalidateLastTime();
}
void PerformanceMetrics::CountThrottleSleep(DT sleep)
{
m_time_sleeping += sleep;

View File

@ -7,7 +7,7 @@
#include <deque>
#include "Common/CommonTypes.h"
#include "Core/Core.h"
#include "Common/HookableEvent.h"
#include "VideoCommon/PerformanceTracker.h"
namespace Core
@ -18,7 +18,7 @@ class System;
class PerformanceMetrics
{
public:
PerformanceMetrics() = default;
PerformanceMetrics();
~PerformanceMetrics() = default;
PerformanceMetrics(const PerformanceMetrics&) = delete;
@ -30,7 +30,6 @@ public:
void CountFrame();
void CountVBlank();
void OnEmulationStateChanged(Core::State state);
// Call from CPU thread.
void CountThrottleSleep(DT sleep);
@ -69,6 +68,8 @@ private:
std::deque<PerfSample> m_samples;
DT m_time_sleeping{};
Common::EventHook m_state_change_hook;
};
extern PerformanceMetrics g_perf_metrics;