diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index acc65525126..13260f71345 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -75,7 +75,7 @@ Settings::Settings() } }); - m_hotplug_callback_handle = g_controller_interface.RegisterDevicesChangedCallback([this] { + m_hotplug_event_hook = g_controller_interface.RegisterDevicesChangedCallback("Settings", [this] { if (Core::IsHostThread()) { emit DevicesChanged(); @@ -101,7 +101,7 @@ Settings::~Settings() void Settings::UnregisterDevicesChangedCallback() { - g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle); + m_hotplug_event_hook.reset(); } Settings& Settings::Instance() diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index cb78e9e5c00..08921e794f4 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -234,7 +234,7 @@ private: std::shared_ptr m_client; std::shared_ptr m_server; - ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle; + Common::EventHook m_hotplug_event_hook; Config::ConfigChangedCallbackID m_config_changed_callback_id; }; diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index 476aaa55371..a11241d4f8d 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -454,8 +454,8 @@ void RegisterDevicesChangedCallbackIfNeeded(JNIEnv* env, jclass controller_inter const jmethodID controller_interface_on_devices_changed = env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V"); - g_controller_interface.RegisterDevicesChangedCallback( - [global_controller_interface_class, controller_interface_on_devices_changed] { + static Common::EventHook event_hook = g_controller_interface.RegisterDevicesChangedCallback( + "Android", [global_controller_interface_class, controller_interface_on_devices_changed] { IDCache::GetEnvForThread()->CallStaticVoidMethod(global_controller_interface_class, controller_interface_on_devices_changed); }); diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index b8651c608df..19ac7d3690e 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -413,27 +413,16 @@ bool ControllerInterface::IsMouseCenteringRequested() const // Register a callback to be called when a device is added or removed (as from the input backends' // hotplug thread), or when devices are refreshed // Returns a handle for later removing the callback. -ControllerInterface::HotplugCallbackHandle -ControllerInterface::RegisterDevicesChangedCallback(std::function callback) -{ - std::lock_guard lk(m_callbacks_mutex); - m_devices_changed_callbacks.emplace_back(std::move(callback)); - return std::prev(m_devices_changed_callbacks.end()); -} -// Unregister a device callback. -void ControllerInterface::UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle) +Common::EventHook +ControllerInterface::RegisterDevicesChangedCallback(std::string_view name, + Common::HookableEvent<>::CallbackType callback) { - std::lock_guard lk(m_callbacks_mutex); - m_devices_changed_callbacks.erase(handle); + return m_devices_changed_event.Register(std::move(callback), name); } // Invoke all callbacks that were registered -void ControllerInterface::InvokeDevicesChangedCallbacks() const +void ControllerInterface::InvokeDevicesChangedCallbacks() { - m_callbacks_mutex.lock(); - const auto devices_changed_callbacks = m_devices_changed_callbacks; - m_callbacks_mutex.unlock(); - for (const auto& callback : devices_changed_callbacks) - callback(); + m_devices_changed_event.Trigger(); } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index e5712f0a4f5..806c6b4b2ac 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -5,12 +5,13 @@ #include #include -#include #include #include +#include "Common/HookableEvent.h" #include "Common/Matrix.h" #include "Common/WindowSystemInfo.h" + #include "InputCommon/ControllerInterface/CoreDevice.h" #include "InputCommon/ControllerInterface/InputBackend.h" @@ -64,8 +65,6 @@ enum class InputChannel class ControllerInterface : public ciface::Core::DeviceContainer { public: - using HotplugCallbackHandle = std::list>::iterator; - enum class WindowChangeReason { // Application is shutting down @@ -115,9 +114,9 @@ public: bool IsMouseCenteringRequested() const; - HotplugCallbackHandle RegisterDevicesChangedCallback(std::function callback); - void UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle); - void InvokeDevicesChangedCallbacks() const; + [[nodiscard]] Common::EventHook + RegisterDevicesChangedCallback(std::string_view name, + Common::HookableEvent<>::CallbackType callback); static void SetCurrentInputChannel(ciface::InputChannel); static ciface::InputChannel GetCurrentInputChannel(); @@ -127,9 +126,11 @@ public: private: void ClearDevices(); - std::list> m_devices_changed_callbacks; + void InvokeDevicesChangedCallbacks(); + + Common::HookableEvent<> m_devices_changed_event{"Devices Changed"}; + mutable std::recursive_mutex m_devices_population_mutex; - mutable std::mutex m_callbacks_mutex; std::atomic m_is_init; // This is now always protected by m_devices_population_mutex, so // it doesn't really need to be a counter or atomic anymore (it could be a raw bool), diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 2dd39f945b9..0e56adf378f 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -172,15 +172,16 @@ void InputConfig::RegisterHotplugCallback() { // Update control references on all controllers // as configured devices may have been added or removed. - m_hotplug_callback_handle = g_controller_interface.RegisterDevicesChangedCallback([this] { - for (auto& controller : m_controllers) - controller->UpdateReferences(g_controller_interface); - }); + m_hotplug_event_hook = + g_controller_interface.RegisterDevicesChangedCallback("InputConfig", [this] { + for (auto& controller : m_controllers) + controller->UpdateReferences(g_controller_interface); + }); } void InputConfig::UnregisterHotplugCallback() { - g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle); + m_hotplug_event_hook.reset(); } bool InputConfig::IsControllerControlledByGamepadDevice(int index) const diff --git a/Source/Core/InputCommon/InputConfig.h b/Source/Core/InputCommon/InputConfig.h index 6cd428a8d86..205f5d36239 100644 --- a/Source/Core/InputCommon/InputConfig.h +++ b/Source/Core/InputCommon/InputConfig.h @@ -58,7 +58,7 @@ public: void GenerateControllerTextures(); private: - ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle; + Common::EventHook m_hotplug_event_hook; std::vector> m_controllers; const std::string m_ini_name; const std::string m_gui_name;