InputCommon: Make ControllerInterface RegisterDevicesChangedCallback use Common::HookableEvent.

This commit is contained in:
Jordan Woyak 2025-11-04 14:36:46 -06:00
parent 2170080f53
commit ca6d8e1f0b
7 changed files with 27 additions and 36 deletions

View File

@ -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()) if (Core::IsHostThread())
{ {
emit DevicesChanged(); emit DevicesChanged();
@ -101,7 +101,7 @@ Settings::~Settings()
void Settings::UnregisterDevicesChangedCallback() void Settings::UnregisterDevicesChangedCallback()
{ {
g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle); m_hotplug_event_hook.reset();
} }
Settings& Settings::Instance() Settings& Settings::Instance()

View File

@ -234,7 +234,7 @@ private:
std::shared_ptr<NetPlay::NetPlayClient> m_client; std::shared_ptr<NetPlay::NetPlayClient> m_client;
std::shared_ptr<NetPlay::NetPlayServer> m_server; std::shared_ptr<NetPlay::NetPlayServer> m_server;
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle; Common::EventHook m_hotplug_event_hook;
Config::ConfigChangedCallbackID m_config_changed_callback_id; Config::ConfigChangedCallbackID m_config_changed_callback_id;
}; };

View File

@ -454,8 +454,8 @@ void RegisterDevicesChangedCallbackIfNeeded(JNIEnv* env, jclass controller_inter
const jmethodID controller_interface_on_devices_changed = const jmethodID controller_interface_on_devices_changed =
env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V"); env->GetStaticMethodID(global_controller_interface_class, "onDevicesChanged", "()V");
g_controller_interface.RegisterDevicesChangedCallback( static Common::EventHook event_hook = g_controller_interface.RegisterDevicesChangedCallback(
[global_controller_interface_class, controller_interface_on_devices_changed] { "Android", [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

@ -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' // 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 // hotplug thread), or when devices are refreshed
// Returns a handle for later removing the callback. // Returns a handle for later removing the callback.
ControllerInterface::HotplugCallbackHandle
ControllerInterface::RegisterDevicesChangedCallback(std::function<void()> 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. Common::EventHook
void ControllerInterface::UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle) ControllerInterface::RegisterDevicesChangedCallback(std::string_view name,
Common::HookableEvent<>::CallbackType callback)
{ {
std::lock_guard lk(m_callbacks_mutex); return m_devices_changed_event.Register(std::move(callback), name);
m_devices_changed_callbacks.erase(handle);
} }
// Invoke all callbacks that were registered // Invoke all callbacks that were registered
void ControllerInterface::InvokeDevicesChangedCallbacks() const void ControllerInterface::InvokeDevicesChangedCallbacks()
{ {
m_callbacks_mutex.lock(); m_devices_changed_event.Trigger();
const auto devices_changed_callbacks = m_devices_changed_callbacks;
m_callbacks_mutex.unlock();
for (const auto& callback : devices_changed_callbacks)
callback();
} }

View File

@ -5,12 +5,13 @@
#include <atomic> #include <atomic>
#include <functional> #include <functional>
#include <list>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include "Common/HookableEvent.h"
#include "Common/Matrix.h" #include "Common/Matrix.h"
#include "Common/WindowSystemInfo.h" #include "Common/WindowSystemInfo.h"
#include "InputCommon/ControllerInterface/CoreDevice.h" #include "InputCommon/ControllerInterface/CoreDevice.h"
#include "InputCommon/ControllerInterface/InputBackend.h" #include "InputCommon/ControllerInterface/InputBackend.h"
@ -64,8 +65,6 @@ enum class InputChannel
class ControllerInterface : public ciface::Core::DeviceContainer class ControllerInterface : public ciface::Core::DeviceContainer
{ {
public: public:
using HotplugCallbackHandle = std::list<std::function<void()>>::iterator;
enum class WindowChangeReason enum class WindowChangeReason
{ {
// Application is shutting down // Application is shutting down
@ -115,9 +114,9 @@ public:
bool IsMouseCenteringRequested() const; bool IsMouseCenteringRequested() const;
HotplugCallbackHandle RegisterDevicesChangedCallback(std::function<void(void)> callback); [[nodiscard]] Common::EventHook
void UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle); RegisterDevicesChangedCallback(std::string_view name,
void InvokeDevicesChangedCallbacks() const; Common::HookableEvent<>::CallbackType callback);
static void SetCurrentInputChannel(ciface::InputChannel); static void SetCurrentInputChannel(ciface::InputChannel);
static ciface::InputChannel GetCurrentInputChannel(); static ciface::InputChannel GetCurrentInputChannel();
@ -127,9 +126,11 @@ public:
private: private:
void ClearDevices(); void ClearDevices();
std::list<std::function<void()>> m_devices_changed_callbacks; void InvokeDevicesChangedCallbacks();
Common::HookableEvent<> m_devices_changed_event{"Devices Changed"};
mutable std::recursive_mutex m_devices_population_mutex; mutable std::recursive_mutex m_devices_population_mutex;
mutable std::mutex m_callbacks_mutex;
std::atomic<bool> m_is_init; std::atomic<bool> m_is_init;
// This is now always protected by m_devices_population_mutex, so // 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), // it doesn't really need to be a counter or atomic anymore (it could be a raw bool),

View File

@ -172,15 +172,16 @@ 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_callback_handle = g_controller_interface.RegisterDevicesChangedCallback([this] { m_hotplug_event_hook =
for (auto& controller : m_controllers) g_controller_interface.RegisterDevicesChangedCallback("InputConfig", [this] {
controller->UpdateReferences(g_controller_interface); for (auto& controller : m_controllers)
}); controller->UpdateReferences(g_controller_interface);
});
} }
void InputConfig::UnregisterHotplugCallback() void InputConfig::UnregisterHotplugCallback()
{ {
g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle); m_hotplug_event_hook.reset();
} }
bool InputConfig::IsControllerControlledByGamepadDevice(int index) const bool InputConfig::IsControllerControlledByGamepadDevice(int index) const

View File

@ -58,7 +58,7 @@ public:
void GenerateControllerTextures(); void GenerateControllerTextures();
private: private:
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle; Common::EventHook m_hotplug_event_hook;
std::vector<std::unique_ptr<ControllerEmu::EmulatedController>> m_controllers; std::vector<std::unique_ptr<ControllerEmu::EmulatedController>> m_controllers;
const std::string m_ini_name; const std::string m_ini_name;
const std::string m_gui_name; const std::string m_gui_name;