Merge pull request #14074 from jordan-woyak/HookableEvent-no-strings

Common: Remove the string parameters from the HookableEvent interface.
This commit is contained in:
Jordan Woyak 2025-11-07 16:32:06 -06:00 committed by GitHub
commit 5af9bd5e46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 83 additions and 125 deletions

View File

@ -6,14 +6,9 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string_view>
#include <vector> #include <vector>
#if defined(_DEBUG)
#include <string>
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#endif
namespace Common namespace Common
{ {
@ -33,12 +28,13 @@ using EventHook = std::unique_ptr<HookBase>;
// //
// Define Events as: // Define Events as:
// //
// HookableEvent<std::string, u32> my_lovely_event{"My lovely event"}; // HookableEvent<std::string, u32> my_lovely_event;
// //
// Register listeners anywhere you need them as: // Register listeners anywhere you need them as:
// EventHook my_hook = my_lovely_event.Register([](std::string foo, u32 bar) { //
// EventHook my_hook = my_lovely_event.Register([](std::string foo, u32 bar) {
// fmt::print("I've been triggered with {} and {}", foo, bar) // fmt::print("I've been triggered with {} and {}", foo, bar)
// }, "NameOfHook"); // });
// //
// The hook will be automatically unregistered when the EventHook object goes out of scope. // The hook will be automatically unregistered when the EventHook object goes out of scope.
// Trigger events by calling Trigger as: // Trigger events by calling Trigger as:
@ -52,19 +48,12 @@ class HookableEvent
public: public:
using CallbackType = std::function<void(CallbackArgs...)>; using CallbackType = std::function<void(CallbackArgs...)>;
explicit HookableEvent(std::string_view event_name)
: m_storage{std::make_shared<Storage>(event_name)}
{
}
// Returns a handle that will unregister the listener when destroyed. // Returns a handle that will unregister the listener when destroyed.
// Note: Attempting to add/remove hooks of the event within the callback itself will NOT work. // Note: Attempting to add/remove hooks of the event within the callback itself will NOT work.
[[nodiscard]] EventHook Register(CallbackType callback, std::string_view name) [[nodiscard]] EventHook Register(CallbackType callback)
{ {
#if defined(_DEBUG) DEBUG_LOG_FMT(COMMON, "Registering event hook handler");
DEBUG_LOG_FMT(COMMON, "Registering {} handler at {} event hook", name, m_storage->event_name); auto handle = std::make_unique<HookImpl>(m_storage, std::move(callback));
#endif
auto handle = std::make_unique<HookImpl>(m_storage, std::move(callback), name);
std::lock_guard lg(m_storage->listeners_mutex); std::lock_guard lg(m_storage->listeners_mutex);
m_storage->listeners.push_back(handle.get()); m_storage->listeners.push_back(handle.get());
@ -83,29 +72,15 @@ private:
struct Storage struct Storage
{ {
explicit Storage(std::string_view name [[maybe_unused]])
{
#if defined(_DEBUG)
event_name = std::string(name);
#endif
}
std::mutex listeners_mutex; std::mutex listeners_mutex;
std::vector<HookImpl*> listeners; std::vector<HookImpl*> listeners;
#if defined(_DEBUG)
std::string event_name;
#endif
}; };
struct HookImpl final : HookBase struct HookImpl final : HookBase
{ {
HookImpl(const std::shared_ptr<Storage> storage, CallbackType func, HookImpl(const std::shared_ptr<Storage> storage, CallbackType func)
std::string_view name [[maybe_unused]])
: weak_storage{storage}, callback{std::move(func)} : weak_storage{storage}, callback{std::move(func)}
{ {
#if defined(_DEBUG)
hook_name = std::string(name);
#endif
} }
~HookImpl() override ~HookImpl() override
@ -113,28 +88,22 @@ private:
const auto storage = weak_storage.lock(); const auto storage = weak_storage.lock();
if (storage == nullptr) if (storage == nullptr)
{ {
#if defined(_DEBUG) DEBUG_LOG_FMT(COMMON, "Handler outlived event hook");
DEBUG_LOG_FMT(COMMON, "Handler {} outlived event hook", hook_name);
#endif
return; return;
} }
#if defined(_DEBUG) DEBUG_LOG_FMT(COMMON, "Removing event hook handler");
DEBUG_LOG_FMT(COMMON, "Removing handler {} of event hook {}", hook_name, storage->event_name);
#endif
std::lock_guard lg(storage->listeners_mutex); std::lock_guard lg(storage->listeners_mutex);
std::erase(storage->listeners, this); std::erase(storage->listeners, this);
} }
std::weak_ptr<Storage> weak_storage; std::weak_ptr<Storage> weak_storage;
const CallbackType callback; const CallbackType callback;
#if defined(_DEBUG)
std::string hook_name;
#endif
}; };
// shared_ptr storage allows hooks to forget their connection if they outlive the event itself. // shared_ptr storage allows hooks to forget their connection if they outlive the event itself.
std::shared_ptr<Storage> m_storage; std::shared_ptr<Storage> m_storage{std::make_shared<Storage>()};
}; };
} // namespace Common } // namespace Common

View File

@ -120,7 +120,7 @@ public:
bool rich_presence = false; bool rich_presence = false;
int failed_login_code = 0; int failed_login_code = 0;
}; };
Common::HookableEvent<const UpdatedItems&> update_event{"AchievementManagerUpdate"}; Common::HookableEvent<const UpdatedItems&> update_event;
static AchievementManager& GetInstance(); static AchievementManager& GetInstance();
void Init(void* hwnd); void Init(void* hwnd);
@ -174,7 +174,7 @@ public:
std::vector<std::string> GetActiveLeaderboards() const; std::vector<std::string> GetActiveLeaderboards() const;
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
Common::HookableEvent<> dev_menu_update_event{"AchievementManagerDevMenuUpdate"}; Common::HookableEvent<> dev_menu_update_event;
const rc_client_raintegration_menu_t* GetDevelopmentMenu(); const rc_client_raintegration_menu_t* GetDevelopmentMenu();
u32 ActivateDevMenuItem(u32 menu_item_id); u32 ActivateDevMenuItem(u32 menu_item_id);
bool CheckForModifications() { return rc_client_raintegration_has_modifications(m_client); } bool CheckForModifications() { return rc_client_raintegration_has_modifications(m_client); }

View File

@ -658,8 +658,8 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
// This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block. // This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
system.GetFifo().Prepare(); system.GetFifo().Prepare();
const Common::EventHook frame_presented = GetVideoEvents().after_present_event.Register( const Common::EventHook frame_presented =
&Core::Callback_FramePresented, "Core Frame Presented"); GetVideoEvents().after_present_event.Register(&Core::Callback_FramePresented);
// Setup our core // Setup our core
if (Config::Get(Config::MAIN_CPU_CORE) != PowerPC::CPUCore::Interpreter) if (Config::Get(Config::MAIN_CPU_CORE) != PowerPC::CPUCore::Interpreter)

View File

@ -250,8 +250,8 @@ void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb)
m_RequestedRecordingEnd = false; m_RequestedRecordingEnd = false;
m_FinishedCb = finishedCb; m_FinishedCb = finishedCb;
m_end_of_frame_event = m_system.GetVideoEvents().after_frame_event.Register( m_end_of_frame_event =
[this](const Core::System& system) { m_system.GetVideoEvents().after_frame_event.Register([this](const Core::System& system) {
const bool was_recording = OpcodeDecoder::g_record_fifo_data; const bool was_recording = OpcodeDecoder::g_record_fifo_data;
OpcodeDecoder::g_record_fifo_data = IsRecording(); OpcodeDecoder::g_record_fifo_data = IsRecording();
@ -270,8 +270,7 @@ void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb)
const auto& fifo = system.GetCommandProcessor().GetFifo(); const auto& fifo = system.GetCommandProcessor().GetFifo();
EndFrame(fifo.CPBase.load(std::memory_order_relaxed), EndFrame(fifo.CPBase.load(std::memory_order_relaxed),
fifo.CPEnd.load(std::memory_order_relaxed)); fifo.CPEnd.load(std::memory_order_relaxed));
}, });
"FifoRecorder::EndFrame");
} }
void FifoRecorder::RecordInitialVideoMemory() void FifoRecorder::RecordInitialVideoMemory()

View File

@ -36,8 +36,7 @@ AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent)
QueueOnObject(this, [this, updated_items = std::move(updated_items)] { QueueOnObject(this, [this, updated_items = std::move(updated_items)] {
AchievementsWindow::UpdateData(std::move(updated_items)); AchievementsWindow::UpdateData(std::move(updated_items));
}); });
}, });
"AchievementsWindow");
UpdateData(AchievementManager::UpdatedItems{.all = true}); UpdateData(AchievementManager::UpdatedItems{.all = true});
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,

View File

@ -79,8 +79,8 @@ void CheatsManager::UpdateAllCheatSearchWidgetCurrentValues()
void CheatsManager::RegisterAfterFrameEventCallback() void CheatsManager::RegisterAfterFrameEventCallback()
{ {
m_VI_end_field_event = m_system.GetVideoEvents().vi_end_field_event.Register( m_VI_end_field_event =
[this] { OnFrameEnd(); }, "CheatsManager"); m_system.GetVideoEvents().vi_end_field_event.Register([this] { OnFrameEnd(); });
} }
void CheatsManager::RemoveAfterFrameEventCallback() void CheatsManager::RemoveAfterFrameEventCallback()

View File

@ -429,8 +429,8 @@ void MemoryWidget::hideEvent(QHideEvent* event)
void MemoryWidget::RegisterAfterFrameEventCallback() void MemoryWidget::RegisterAfterFrameEventCallback()
{ {
m_vi_end_field_event = m_system.GetVideoEvents().vi_end_field_event.Register( m_vi_end_field_event =
[this] { AutoUpdateTable(); }, "MemoryWidget"); m_system.GetVideoEvents().vi_end_field_event.Register([this] { AutoUpdateTable(); });
} }
void MemoryWidget::RemoveAfterFrameEventCallback() void MemoryWidget::RemoveAfterFrameEventCallback()

View File

@ -296,7 +296,7 @@ void MenuBar::AddToolsMenu()
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
m_achievements_dev_menu = tools_menu->addMenu(tr("RetroAchievements Development")); m_achievements_dev_menu = tools_menu->addMenu(tr("RetroAchievements Development"));
m_raintegration_event_hook = AchievementManager::GetInstance().dev_menu_update_event.Register( m_raintegration_event_hook = AchievementManager::GetInstance().dev_menu_update_event.Register(
[this] { QueueOnObject(this, [this] { UpdateAchievementDevelopmentMenu(); }); }, "MenuBar"); [this] { QueueOnObject(this, [this] { UpdateAchievementDevelopmentMenu(); }); });
m_achievements_dev_menu->menuAction()->setVisible(false); m_achievements_dev_menu->menuAction()->setVisible(false);
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION #endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
tools_menu->addSeparator(); tools_menu->addSeparator();

View File

@ -75,7 +75,7 @@ Settings::Settings()
} }
}); });
m_hotplug_event_hook = g_controller_interface.RegisterDevicesChangedCallback("Settings", [this] { m_hotplug_event_hook = g_controller_interface.RegisterDevicesChangedCallback([this] {
if (Core::IsHostThread()) if (Core::IsHostThread())
{ {
emit DevicesChanged(); emit DevicesChanged();

View File

@ -455,7 +455,7 @@ void RegisterDevicesChangedCallbackIfNeeded(JNIEnv* env, jclass controller_inter
env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V"); env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V");
static Common::EventHook event_hook = g_controller_interface.RegisterDevicesChangedCallback( static Common::EventHook event_hook = g_controller_interface.RegisterDevicesChangedCallback(
"Android", [global_controller_interface_class, controller_interface_on_devices_changed] { [global_controller_interface_class, controller_interface_on_devices_changed] {
IDCache::GetEnvForThread()->CallStaticVoidMethod(global_controller_interface_class, IDCache::GetEnvForThread()->CallStaticVoidMethod(global_controller_interface_class,
controller_interface_on_devices_changed); controller_interface_on_devices_changed);
}); });

View File

@ -415,10 +415,9 @@ bool ControllerInterface::IsMouseCenteringRequested() const
// Returns a handle for later removing the callback. // Returns a handle for later removing the callback.
Common::EventHook Common::EventHook
ControllerInterface::RegisterDevicesChangedCallback(std::string_view name, ControllerInterface::RegisterDevicesChangedCallback(Common::HookableEvent<>::CallbackType callback)
Common::HookableEvent<>::CallbackType callback)
{ {
return m_devices_changed_event.Register(std::move(callback), name); return m_devices_changed_event.Register(std::move(callback));
} }
// Invoke all callbacks that were registered // Invoke all callbacks that were registered

View File

@ -115,8 +115,7 @@ public:
bool IsMouseCenteringRequested() const; bool IsMouseCenteringRequested() const;
[[nodiscard]] Common::EventHook [[nodiscard]] Common::EventHook
RegisterDevicesChangedCallback(std::string_view name, RegisterDevicesChangedCallback(Common::HookableEvent<>::CallbackType callback);
Common::HookableEvent<>::CallbackType callback);
static void SetCurrentInputChannel(ciface::InputChannel); static void SetCurrentInputChannel(ciface::InputChannel);
static ciface::InputChannel GetCurrentInputChannel(); static ciface::InputChannel GetCurrentInputChannel();
@ -128,7 +127,7 @@ private:
void InvokeDevicesChangedCallbacks(); void InvokeDevicesChangedCallbacks();
Common::HookableEvent<> m_devices_changed_event{"Devices Changed"}; Common::HookableEvent<> m_devices_changed_event;
mutable std::recursive_mutex m_devices_population_mutex; mutable std::recursive_mutex m_devices_population_mutex;
std::atomic<bool> m_is_init; std::atomic<bool> m_is_init;

View File

@ -172,11 +172,10 @@ void InputConfig::RegisterHotplugCallback()
{ {
// Update control references on all controllers // Update control references on all controllers
// as configured devices may have been added or removed. // as configured devices may have been added or removed.
m_hotplug_event_hook = m_hotplug_event_hook = g_controller_interface.RegisterDevicesChangedCallback([this] {
g_controller_interface.RegisterDevicesChangedCallback("InputConfig", [this] { for (auto& controller : m_controllers)
for (auto& controller : m_controllers) controller->UpdateReferences(g_controller_interface);
controller->UpdateReferences(g_controller_interface); });
});
} }
void InputConfig::UnregisterHotplugCallback() void InputConfig::UnregisterHotplugCallback()

View File

@ -18,8 +18,8 @@ std::unique_ptr<AbstractGfx> g_gfx;
AbstractGfx::AbstractGfx() AbstractGfx::AbstractGfx()
{ {
m_config_changed = GetVideoEvents().config_changed_event.Register( m_config_changed =
[this](u32 bits) { OnConfigChanged(bits); }, "AbstractGfx"); GetVideoEvents().config_changed_event.Register([this](u32 bits) { OnConfigChanged(bits); });
} }
bool AbstractGfx::IsHeadless() const bool AbstractGfx::IsHeadless() const

View File

@ -29,8 +29,8 @@ void CustomResourceManager::Initialize()
m_asset_loader.Initialize(); m_asset_loader.Initialize();
m_xfb_event = GetVideoEvents().after_frame_event.Register( m_xfb_event =
[this](Core::System&) { XFBTriggered(); }, "CustomResourceManager"); GetVideoEvents().after_frame_event.Register([this](Core::System&) { XFBTriggered(); });
} }
void CustomResourceManager::Shutdown() void CustomResourceManager::Shutdown()

View File

@ -29,8 +29,8 @@ static bool DumpFrameToPNG(const FrameData& frame, const std::string& file_name)
FrameDumper::FrameDumper() FrameDumper::FrameDumper()
{ {
m_frame_end_handle = GetVideoEvents().after_frame_event.Register( m_frame_end_handle =
[this](Core::System&) { FlushFrameDump(); }, "FrameDumper"); GetVideoEvents().after_frame_event.Register([this](Core::System&) { FlushFrameDump(); });
} }
FrameDumper::~FrameDumper() FrameDumper::~FrameDumper()

View File

@ -84,8 +84,8 @@ bool FramebufferManager::Initialize()
return false; return false;
} }
m_end_of_frame_event = GetVideoEvents().after_frame_event.Register( m_end_of_frame_event =
[this](Core::System&) { EndOfFrame(); }, "FramebufferManager"); GetVideoEvents().after_frame_event.Register([this](Core::System&) { EndOfFrame(); });
return true; return true;
} }

View File

@ -18,7 +18,7 @@ CustomShaderCache::CustomShaderCache()
m_async_uber_shader_compiler->StartWorkerThreads(1); // TODO m_async_uber_shader_compiler->StartWorkerThreads(1); // TODO
m_frame_end_handler = GetVideoEvents().after_frame_event.Register( m_frame_end_handler = GetVideoEvents().after_frame_event.Register(
[this](Core::System&) { RetrieveAsyncShaders(); }, "RetrieveAsyncShaders"); [this](Core::System&) { RetrieveAsyncShaders(); });
} }
CustomShaderCache::~CustomShaderCache() CustomShaderCache::~CustomShaderCache()

View File

@ -95,8 +95,8 @@ bool GraphicsModManager::Initialize()
g_ActiveConfig.graphics_mod_config->SetChangeCount(old_game_mod_changes); g_ActiveConfig.graphics_mod_config->SetChangeCount(old_game_mod_changes);
g_graphics_mod_manager->Load(*g_ActiveConfig.graphics_mod_config); g_graphics_mod_manager->Load(*g_ActiveConfig.graphics_mod_config);
m_end_of_frame_event = GetVideoEvents().after_frame_event.Register( m_end_of_frame_event =
[this](Core::System&) { EndOfFrame(); }, "ModManager"); GetVideoEvents().after_frame_event.Register([this](Core::System&) { EndOfFrame(); });
} }
return true; return true;

View File

@ -94,8 +94,8 @@ static void TryToSnapToXFBSize(int& width, int& height, int xfb_width, int xfb_h
Presenter::Presenter() Presenter::Presenter()
{ {
m_config_changed = GetVideoEvents().config_changed_event.Register( m_config_changed =
[this](u32 bits) { ConfigChanged(bits); }, "Presenter"); GetVideoEvents().config_changed_event.Register([this](u32 bits) { ConfigChanged(bits); });
} }
Presenter::~Presenter() Presenter::~Presenter()

View File

@ -47,7 +47,7 @@ bool ShaderCache::Initialize()
m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler(); m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();
m_frame_end_handler = GetVideoEvents().after_frame_event.Register( m_frame_end_handler = GetVideoEvents().after_frame_event.Register(
[this](Core::System&) { RetrieveAsyncShaders(); }, "RetrieveAsyncShaders"); [this](Core::System&) { RetrieveAsyncShaders(); });
return true; return true;
} }

View File

@ -500,18 +500,15 @@ void Statistics::DisplayScissor()
void Statistics::Init() void Statistics::Init()
{ {
s_before_frame_event = GetVideoEvents().before_frame_event.Register([] { g_stats.ResetFrame(); }, s_before_frame_event = GetVideoEvents().before_frame_event.Register([] { g_stats.ResetFrame(); });
"Statistics::ResetFrame");
s_after_frame_event = GetVideoEvents().after_frame_event.Register( s_after_frame_event = GetVideoEvents().after_frame_event.Register([](const Core::System& system) {
[](const Core::System& system) { DolphinAnalytics::Instance().ReportPerformanceInfo({
DolphinAnalytics::Instance().ReportPerformanceInfo({ .speed_ratio = system.GetSystemTimers().GetEstimatedEmulationPerformance(),
.speed_ratio = system.GetSystemTimers().GetEstimatedEmulationPerformance(), .num_prims = g_stats.this_frame.num_prims + g_stats.this_frame.num_dl_prims,
.num_prims = g_stats.this_frame.num_prims + g_stats.this_frame.num_dl_prims, .num_draw_calls = g_stats.this_frame.num_draw_calls,
.num_draw_calls = g_stats.this_frame.num_draw_calls, });
}); });
},
"Statistics::PerformanceSample");
} }
void Statistics::Shutdown() void Statistics::Shutdown()

View File

@ -463,8 +463,8 @@ private:
void OnFrameEnd(); void OnFrameEnd();
Common::EventHook m_frame_event = GetVideoEvents().after_frame_event.Register( Common::EventHook m_frame_event =
[this](Core::System&) { OnFrameEnd(); }, "TextureCache"); GetVideoEvents().after_frame_event.Register([this](Core::System&) { OnFrameEnd(); });
VideoCommon::TextureUtils::TextureDumper m_texture_dumper; VideoCommon::TextureUtils::TextureDumper m_texture_dumper;
}; };

View File

@ -120,11 +120,10 @@ bool VertexManagerBase::Initialize()
{ {
auto& video_events = GetVideoEvents(); auto& video_events = GetVideoEvents();
m_frame_end_event = video_events.after_frame_event.Register( m_frame_end_event =
[this](Core::System&) { OnEndFrame(); }, "VertexManagerBase"); video_events.after_frame_event.Register([this](Core::System&) { OnEndFrame(); });
m_after_present_event = video_events.after_present_event.Register( m_after_present_event = video_events.after_present_event.Register(
[this](const PresentInfo& pi) { m_ticks_elapsed = pi.emulated_timestamp; }, [this](const PresentInfo& pi) { m_ticks_elapsed = pi.emulated_timestamp; });
"VertexManagerBase");
m_index_generator.Init(); m_index_generator.Init();
m_custom_shader_cache = std::make_unique<CustomShaderCache>(); m_custom_shader_cache = std::make_unique<CustomShaderCache>();
m_cpu_cull.Init(); m_cpu_cull.Init();

View File

@ -221,8 +221,8 @@ void VideoConfig::VerifyValidity()
void VideoConfig::Init() void VideoConfig::Init()
{ {
s_check_config_event = GetVideoEvents().after_frame_event.Register( s_check_config_event =
[](Core::System&) { CheckForConfigChanges(); }, "CheckForConfigChanges"); GetVideoEvents().after_frame_event.Register([](Core::System&) { CheckForConfigChanges(); });
} }
void VideoConfig::Shutdown() void VideoConfig::Shutdown()

View File

@ -69,17 +69,17 @@ struct PresentInfo
struct VideoEvents struct VideoEvents
{ {
// Called when certain video config setting are changed // Called when certain video config setting are changed
Common::HookableEvent<u32> config_changed_event{"ConfigChanged"}; Common::HookableEvent<u32> config_changed_event;
// An event called just before the first draw call of a frame // An event called just before the first draw call of a frame
Common::HookableEvent<> before_frame_event{"BeforeFrame"}; Common::HookableEvent<> before_frame_event;
// An event called after the frame XFB copy begins processing on the host GPU. // An event called after the frame XFB copy begins processing on the host GPU.
// Useful for "once per frame" usecases. // Useful for "once per frame" usecases.
// Note: In a few rare cases, games do multiple XFB copies per frame and join them while // Note: In a few rare cases, games do multiple XFB copies per frame and join them while
// presenting. // presenting.
// If this matters to your usecase, you should use BeforePresent instead. // If this matters to your usecase, you should use BeforePresent instead.
Common::HookableEvent<Core::System&> after_frame_event{"AfterFrame"}; Common::HookableEvent<Core::System&> after_frame_event;
// An event called just as a frame is queued for presentation. // An event called just as a frame is queued for presentation.
// The exact timing of this event depends on the "Immediately Present XFB" option. // The exact timing of this event depends on the "Immediately Present XFB" option.
@ -89,14 +89,14 @@ struct VideoEvents
// frame. // frame.
// //
// frame_count: The number of frames // frame_count: The number of frames
Common::HookableEvent<PresentInfo&> before_present_event{"BeforePresent"}; Common::HookableEvent<PresentInfo&> before_present_event;
// An event that is triggered after a frame is presented. // An event that is triggered after a frame is presented.
// The exact timing of this event depends on backend/driver support. // The exact timing of this event depends on backend/driver support.
Common::HookableEvent<PresentInfo&> after_present_event{"AfterPresent"}; Common::HookableEvent<PresentInfo&> after_present_event;
// An end of frame event that runs on the CPU thread // An end of frame event that runs on the CPU thread
Common::HookableEvent<> vi_end_field_event{"VIEndField"}; Common::HookableEvent<> vi_end_field_event;
}; };
VideoEvents& GetVideoEvents(); VideoEvents& GetVideoEvents();

View File

@ -32,26 +32,24 @@ WidescreenManager::WidescreenManager()
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& video_events = system.GetVideoEvents(); auto& video_events = system.GetVideoEvents();
m_config_changed = video_events.config_changed_event.Register( m_config_changed = video_events.config_changed_event.Register([this](u32 bits) {
[this](u32 bits) { if (bits & (CONFIG_CHANGE_BIT_ASPECT_RATIO))
if (bits & (CONFIG_CHANGE_BIT_ASPECT_RATIO)) {
{ // If the widescreen flag isn't being overridden by any settings,
// If the widescreen flag isn't being overridden by any settings, // reset it to default if heuristic aren't running or to the last
// reset it to default if heuristic aren't running or to the last // heuristic value if they were running.
// heuristic value if they were running. if (std::optional<bool> is_game_widescreen = GetWidescreenOverride())
if (std::optional<bool> is_game_widescreen = GetWidescreenOverride()) m_is_game_widescreen = *is_game_widescreen;
m_is_game_widescreen = *is_game_widescreen; else
else m_is_game_widescreen = (m_heuristic_state == HeuristicState::Active_Found_Anamorphic);
m_is_game_widescreen = (m_heuristic_state == HeuristicState::Active_Found_Anamorphic); }
} });
},
"Widescreen");
// VertexManager doesn't maintain statistics in Wii mode. // VertexManager doesn't maintain statistics in Wii mode.
if (!system.IsWii()) if (!system.IsWii())
{ {
m_update_widescreen = video_events.after_frame_event.Register( m_update_widescreen = video_events.after_frame_event.Register(
[this](Core::System&) { UpdateWidescreenHeuristic(); }, "WideScreen Heuristic"); [this](Core::System&) { UpdateWidescreenHeuristic(); });
} }
} }