ControllerInterface: make real Wiimote use PlatformPopulateDevices()

This commit is contained in:
Filoppi 2021-05-15 12:10:00 +03:00
parent c238e49119
commit 1d816f8f26
4 changed files with 38 additions and 13 deletions

View File

@ -96,8 +96,15 @@ static void TryToFillWiimoteSlot(u32 index)
s_wiimote_pool.erase(s_wiimote_pool.begin()); s_wiimote_pool.erase(s_wiimote_pool.begin());
} }
void PopulateDevices()
{
// There is a very small chance of deadlocks if we didn't do it in another thread
s_wiimote_scanner.PopulateDevices();
}
// Attempts to fill enabled real wiimote slots. // Attempts to fill enabled real wiimote slots.
// Push/pull wiimotes to/from ControllerInterface as needed. // Push/pull wiimotes to/from ControllerInterface as needed.
// Should be called PopulateDevices() to be in line with other implementations.
void ProcessWiimotePool() void ProcessWiimotePool()
{ {
std::lock_guard lk(g_wiimotes_mutex); std::lock_guard lk(g_wiimotes_mutex);
@ -545,7 +552,7 @@ void WiimoteScanner::StopThread()
void WiimoteScanner::SetScanMode(WiimoteScanMode scan_mode) void WiimoteScanner::SetScanMode(WiimoteScanMode scan_mode)
{ {
m_scan_mode.store(scan_mode); m_scan_mode.store(scan_mode);
m_scan_mode_changed_event.Set(); m_scan_mode_changed_or_population_event.Set();
} }
bool WiimoteScanner::IsReady() const bool WiimoteScanner::IsReady() const
@ -610,6 +617,12 @@ void WiimoteScanner::PoolThreadFunc()
} }
} }
void WiimoteScanner::PopulateDevices()
{
m_populate_devices.Set();
m_scan_mode_changed_or_population_event.Set();
}
void WiimoteScanner::ThreadFunc() void WiimoteScanner::ThreadFunc()
{ {
std::thread pool_thread(&WiimoteScanner::PoolThreadFunc, this); std::thread pool_thread(&WiimoteScanner::PoolThreadFunc, this);
@ -634,7 +647,12 @@ void WiimoteScanner::ThreadFunc()
while (m_scan_thread_running.IsSet()) while (m_scan_thread_running.IsSet())
{ {
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500)); m_scan_mode_changed_or_population_event.WaitFor(std::chrono::milliseconds(500));
if (m_populate_devices.TestAndClear())
{
g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); });
}
// Does stuff needed to detect disconnects on Windows // Does stuff needed to detect disconnects on Windows
for (const auto& backend : m_backends) for (const auto& backend : m_backends)
@ -675,7 +693,7 @@ void WiimoteScanner::ThreadFunc()
} }
AddWiimoteToPool(std::unique_ptr<Wiimote>(wiimote)); AddWiimoteToPool(std::unique_ptr<Wiimote>(wiimote));
ProcessWiimotePool(); g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); });
} }
if (found_board) if (found_board)
@ -956,12 +974,12 @@ void HandleWiimoteSourceChange(unsigned int index)
if (auto removed_wiimote = std::move(g_wiimotes[index])) if (auto removed_wiimote = std::move(g_wiimotes[index]))
AddWiimoteToPool(std::move(removed_wiimote)); AddWiimoteToPool(std::move(removed_wiimote));
}); });
ProcessWiimotePool(); g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); });
} }
void HandleWiimotesInControllerInterfaceSettingChange() void HandleWiimotesInControllerInterfaceSettingChange()
{ {
ProcessWiimotePool(); g_controller_interface.PlatformPopulateDevices([] { ProcessWiimotePool(); });
} }
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -171,6 +171,7 @@ public:
void StartThread(); void StartThread();
void StopThread(); void StopThread();
void SetScanMode(WiimoteScanMode scan_mode); void SetScanMode(WiimoteScanMode scan_mode);
void PopulateDevices();
bool IsReady() const; bool IsReady() const;
@ -183,7 +184,8 @@ private:
std::thread m_scan_thread; std::thread m_scan_thread;
Common::Flag m_scan_thread_running; Common::Flag m_scan_thread_running;
Common::Event m_scan_mode_changed_event; Common::Flag m_populate_devices;
Common::Event m_scan_mode_changed_or_population_event;
std::atomic<WiimoteScanMode> m_scan_mode{WiimoteScanMode::DO_NOT_SCAN}; std::atomic<WiimoteScanMode> m_scan_mode{WiimoteScanMode::DO_NOT_SCAN};
}; };
@ -204,6 +206,7 @@ void InitAdapterClass();
#endif #endif
void HandleWiimotesInControllerInterfaceSettingChange(); void HandleWiimotesInControllerInterfaceSettingChange();
void PopulateDevices();
void ProcessWiimotePool(); void ProcessWiimotePool();
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -185,7 +185,7 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
ciface::DualShockUDPClient::PopulateDevices(); ciface::DualShockUDPClient::PopulateDevices();
#endif #endif
WiimoteReal::ProcessWiimotePool(); WiimoteReal::PopulateDevices();
m_devices_mutex.unlock(); m_devices_mutex.unlock();

View File

@ -128,13 +128,17 @@ void ReleaseDevices(std::optional<u32> count)
// Remove up to "count" remotes (or all of them if nullopt). // Remove up to "count" remotes (or all of them if nullopt).
// Real wiimotes will be added to the pool. // Real wiimotes will be added to the pool.
g_controller_interface.RemoveDevice([&](const Core::Device* device) { // Make sure to force the device removal immediately (as they are shared ptrs and
// they could be kept alive, preventing us from re-creating the device)
g_controller_interface.RemoveDevice(
[&](const Core::Device* device) {
if (device->GetSource() != SOURCE_NAME || count == removed_devices) if (device->GetSource() != SOURCE_NAME || count == removed_devices)
return false; return false;
++removed_devices; ++removed_devices;
return true; return true;
}); },
true);
} }
Device::Device(std::unique_ptr<WiimoteReal::Wiimote> wiimote) : m_wiimote(std::move(wiimote)) Device::Device(std::unique_ptr<WiimoteReal::Wiimote> wiimote) : m_wiimote(std::move(wiimote))