mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 22:00:39 -06:00
Qt: Fix IOWindow keeping a shared ptr to devices even after them being removed by the ControllerInterface
this prevented some devices from being recreated correctly, as they were exclusive (e.g. DInput Joysticks) This is achieved by calling Settings::ReleaseDevices(), which releases all the UI devices shared ptrs. If we are the host (Qt) thread, DevicesChanged() is now called in line, to avoid devices being hanged onto by the UI. For this, I had to add a method to check whether we are the Host Thread to Qt. Avoid calling ControllerInterface::RefreshDevices() from the CPU thread if the emulation is running and we manually refresh devices from Qt, as that is not necessary anymore. Refactored the way IOWindow lists devices to make it clearer and hold onto disconnected devices. There were so many issues with the previous code: -Devices changes would not be reflected until the window was re-opened -If there was no default device, it would fail to select the device at index 0 -It could have crashed if we had 0 devices -The default device was not highlighted as such
This commit is contained in:
@ -25,6 +25,7 @@
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "Core/NetPlayServer.h"
|
||||
|
||||
#include "DolphinQt/Host.h"
|
||||
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
||||
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
@ -44,8 +45,24 @@ Settings::Settings()
|
||||
Config::AddConfigChangedCallback(
|
||||
[this] { QueueOnObject(this, [this] { emit ConfigChanged(); }); });
|
||||
|
||||
g_controller_interface.RegisterDevicesChangedCallback(
|
||||
[this] { QueueOnObject(this, [this] { emit DevicesChanged(); }); });
|
||||
g_controller_interface.RegisterDevicesChangedCallback([this] {
|
||||
if (Host::GetInstance()->IsHostThread())
|
||||
{
|
||||
emit DevicesChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any device shared_ptr in the host thread needs to be released immediately as otherwise
|
||||
// they'd continue living until the queued event has run, but some devices can't be recreated
|
||||
// until they are destroyed.
|
||||
// This is safe from any thread. Devices will be refreshed and re-acquired and in
|
||||
// DevicesChanged(). Waiting on QueueOnObject() to have finished running was not feasible as
|
||||
// it would cause deadlocks without heavy workarounds.
|
||||
emit ReleaseDevices();
|
||||
|
||||
QueueOnObject(this, [this] { emit DevicesChanged(); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Settings::~Settings() = default;
|
||||
|
Reference in New Issue
Block a user