summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-06-07 12:15:15 +0200
committerGitHub <noreply@github.com>2021-06-07 12:15:15 +0200
commit8ca6ffd908aa95ffb5c7665083463c4ea1139b0d (patch)
tree5a058d8aa001d2577f7e65d5aa44ec86737c3386 /Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
parentebe3fbe04c329f9bc100ded4dcf22720f375e2f4 (diff)
parent83ea16f40238fa82981221ba65061a7094b2a64b (diff)
Merge pull request #9702 from Filoppi/controller_interface_fixes
Controller Interface refactor
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/ControllerInterface.h')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/ControllerInterface.h42
1 files changed, 37 insertions, 5 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
index 12d17614da..9c91d853e7 100644
--- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
+++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
@@ -60,13 +60,38 @@ class ControllerInterface : public ciface::Core::DeviceContainer
public:
using HotplugCallbackHandle = std::list<std::function<void()>>::iterator;
+ enum class WindowChangeReason
+ {
+ // Application is shutting down
+ Exit,
+ Other
+ };
+
+ enum class RefreshReason
+ {
+ // Only the window changed.
+ WindowChangeOnly,
+ // User requested, or any other internal reason (e.g. init).
+ // The window might have changed anyway.
+ Other
+ };
+
ControllerInterface() : m_is_init(false) {}
void Initialize(const WindowSystemInfo& wsi);
- void ChangeWindow(void* hwnd);
- void RefreshDevices();
+ // Only call from one thread at a time.
+ void ChangeWindow(void* hwnd, WindowChangeReason reason = WindowChangeReason::Other);
+ // Can be called by any thread at any time (when initialized).
+ void RefreshDevices(RefreshReason reason = RefreshReason::Other);
void Shutdown();
- void AddDevice(std::shared_ptr<ciface::Core::Device> device);
- void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback);
+ bool AddDevice(std::shared_ptr<ciface::Core::Device> device);
+ // Removes all the devices the function returns true to.
+ // If all the devices shared ptrs need to be destroyed immediately,
+ // set force_devices_release to true.
+ void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback,
+ bool force_devices_release = false);
+ // This is mandatory to use on device populations functions that can be called concurrently by
+ // more than one thread, or that are called by a single other thread.
+ // Without this, our devices list might end up in a mixed state.
void PlatformPopulateDevices(std::function<void()> callback);
bool IsInit() const { return m_is_init; }
void UpdateInput();
@@ -87,10 +112,17 @@ public:
static ciface::InputChannel GetCurrentInputChannel();
private:
+ void ClearDevices();
+
std::list<std::function<void()>> m_devices_changed_callbacks;
+ mutable std::recursive_mutex m_devices_population_mutex;
+ mutable std::mutex m_pre_population_mutex;
mutable std::mutex m_callbacks_mutex;
std::atomic<bool> m_is_init;
- std::atomic<bool> m_is_populating_devices{false};
+ // 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),
+ // but we keep it so for simplicity, in case we changed the design.
+ std::atomic<int> m_populating_devices_counter;
WindowSystemInfo m_wsi;
std::atomic<float> m_aspect_ratio_adjustment = 1;
};