ControllerInterface: mixed comments

This commit is contained in:
Filoppi 2021-05-15 11:32:00 +03:00
parent c285ae57fb
commit f90d851e25
5 changed files with 21 additions and 0 deletions

View File

@ -37,6 +37,10 @@
ControllerInterface g_controller_interface; ControllerInterface g_controller_interface;
// We need to save which input channel we are in by thread, so we can access the correct input
// update values in different threads by input channel. We start from InputChannel::Host on all
// threads as hotkeys are updated from a worker thread, but UI can read from the main thread. This
// will never interfere with game threads.
static thread_local ciface::InputChannel tls_input_channel = ciface::InputChannel::Host; static thread_local ciface::InputChannel tls_input_channel = ciface::InputChannel::Host;
void ControllerInterface::Initialize(const WindowSystemInfo& wsi) void ControllerInterface::Initialize(const WindowSystemInfo& wsi)
@ -272,7 +276,11 @@ void ControllerInterface::UpdateInput()
{ {
std::lock_guard lk(m_devices_mutex, std::adopt_lock); std::lock_guard lk(m_devices_mutex, std::adopt_lock);
for (const auto& d : m_devices) for (const auto& d : m_devices)
{
// Theoretically we could avoid updating input on devices that don't have any references to
// them, but in practice a few devices types could break in different ways, so we don't
d->UpdateInput(); d->UpdateInput();
}
} }
} }

View File

@ -67,6 +67,9 @@ public:
void Shutdown(); void Shutdown();
void AddDevice(std::shared_ptr<ciface::Core::Device> device); void AddDevice(std::shared_ptr<ciface::Core::Device> device);
void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback); void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback);
// 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); void PlatformPopulateDevices(std::function<void()> callback);
bool IsInit() const { return m_is_init; } bool IsInit() const { return m_is_init; }
void UpdateInput(); void UpdateInput();

View File

@ -227,6 +227,7 @@ public:
std::chrono::milliseconds maximum_wait) const; std::chrono::milliseconds maximum_wait) const;
protected: protected:
// Exclusively needed when reading/writing "m_devices"
mutable std::recursive_mutex m_devices_mutex; mutable std::recursive_mutex m_devices_mutex;
std::vector<std::shared_ptr<Device>> m_devices; std::vector<std::shared_ptr<Device>> m_devices;
}; };

View File

@ -91,6 +91,11 @@ KeyboardMouse::~KeyboardMouse()
{ {
s_keyboard_mouse_exists = false; s_keyboard_mouse_exists = false;
// Independently of the order in which we do these, if we put a breakpoint on Unacquire() (or in
// any place in the call stack before this), when refreshing devices from the UI, on the second
// attempt, it will get stuck in an infinite (while) loop inside dinput8.dll. Given that it can't
// be otherwise be reproduced (not even with sleeps), we can just ignore the problem.
// kb // kb
m_kb_device->Unacquire(); m_kb_device->Unacquire();
m_kb_device->Release(); m_kb_device->Release();

View File

@ -34,6 +34,7 @@ private:
RelativeMouseState relative_mouse; RelativeMouseState relative_mouse;
}; };
// Keyboard key
class Key : public Input class Key : public Input
{ {
public: public:
@ -46,6 +47,7 @@ private:
const u8 m_index; const u8 m_index;
}; };
// Mouse button
class Button : public Input class Button : public Input
{ {
public: public:
@ -58,6 +60,7 @@ private:
const u8 m_index; const u8 m_index;
}; };
// Mouse movement offset axis. Includes mouse wheel
class Axis : public Input class Axis : public Input
{ {
public: public:
@ -72,6 +75,7 @@ private:
const u8 m_index; const u8 m_index;
}; };
// Mouse from window center
class Cursor : public Input class Cursor : public Input
{ {
public: public: