diff --git a/Source/Core/Core/HW/WiimoteReal/IOAndroid.h b/Source/Core/Core/HW/WiimoteReal/IOAndroid.h index 1802002a42..4447d6ba3e 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOAndroid.h +++ b/Source/Core/Core/HW/WiimoteReal/IOAndroid.h @@ -48,6 +48,7 @@ public: bool IsReady() const override { return true; } void FindWiimotes(std::vector&, Wiimote*&) override; void Update() override {} + void RequestStopSearching() override {} }; } // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/IODummy.h b/Source/Core/Core/HW/WiimoteReal/IODummy.h index 3d85fb94c9..9e4423ece6 100644 --- a/Source/Core/Core/HW/WiimoteReal/IODummy.h +++ b/Source/Core/Core/HW/WiimoteReal/IODummy.h @@ -16,5 +16,6 @@ public: bool IsReady() const override { return false; } void FindWiimotes(std::vector&, Wiimote*&) override {} void Update() override {} + void RequestStopSearching() override {} }; } // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/IOLinux.h b/Source/Core/Core/HW/WiimoteReal/IOLinux.h index 665e91bd4d..0269991740 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOLinux.h +++ b/Source/Core/Core/HW/WiimoteReal/IOLinux.h @@ -46,7 +46,8 @@ public: ~WiimoteScannerLinux() override; bool IsReady() const override; void FindWiimotes(std::vector&, Wiimote*&) override; - void Update() override {} // not needed on Linux + void Update() override {} // not needed on Linux + void RequestStopSearching() override {} // not needed on Linux private: int m_device_id; int m_device_sock; diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.h b/Source/Core/Core/HW/WiimoteReal/IOWin.h index bdca060553..fdad972f74 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOWin.h +++ b/Source/Core/Core/HW/WiimoteReal/IOWin.h @@ -52,6 +52,7 @@ public: bool IsReady() const override; void FindWiimotes(std::vector&, Wiimote*&) override; void Update() override; + void RequestStopSearching() override {} }; } // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.h b/Source/Core/Core/HW/WiimoteReal/IOdarwin.h index ee0b4b9273..fd474b6048 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.h +++ b/Source/Core/Core/HW/WiimoteReal/IOdarwin.h @@ -7,18 +7,28 @@ #ifdef __APPLE__ #include "Core/HW/WiimoteReal/WiimoteReal.h" +#ifdef __OBJC__ +#import +#else +// IOBluetooth's types won't be defined in pure C++ mode. +typedef void IOBluetoothHostController; +#endif + namespace WiimoteReal { class WiimoteScannerDarwin final : public WiimoteScannerBackend { public: - WiimoteScannerDarwin() = default; + WiimoteScannerDarwin(); ~WiimoteScannerDarwin() override; bool IsReady() const override; void FindWiimotes(std::vector&, Wiimote*&) override; void Update() override {} // not needed + void RequestStopSearching() override { m_stop_scanning = true; } + private: - bool stopScanning = false; + IOBluetoothHostController* m_host_controller; + bool m_stop_scanning = false; }; } // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm index a5b2891a32..34d10b083d 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm @@ -21,28 +21,41 @@ namespace WiimoteReal { +WiimoteScannerDarwin::WiimoteScannerDarwin() +{ + m_host_controller = [IOBluetoothHostController defaultController]; + if (![m_host_controller addressAsString]) + { + WARN_LOG_FMT(WIIMOTE, "No Bluetooth host controller"); + + [m_host_controller release]; + m_host_controller = nil; + + return; + } + + [m_host_controller retain]; +} + WiimoteScannerDarwin::~WiimoteScannerDarwin() { - stopScanning = true; + [m_host_controller release]; + m_host_controller = nil; + + m_stop_scanning = true; } void WiimoteScannerDarwin::FindWiimotes(std::vector& found_wiimotes, Wiimote*& found_board) { - // TODO: find the device in the constructor and save it for later - IOBluetoothHostController* bth; - IOBluetoothDeviceInquiry* bti; - found_board = nullptr; - - bth = [[IOBluetoothHostController alloc] init]; - bool btFailed = [bth addressAsString] == nil; - if (btFailed) + if (!m_host_controller) { - WARN_LOG_FMT(WIIMOTE, "No Bluetooth host controller"); - [bth release]; return; } + IOBluetoothDeviceInquiry* bti; + found_board = nullptr; + SearchBT* sbt = [[SearchBT alloc] init]; sbt->maxDevices = 32; bti = [[IOBluetoothDeviceInquiry alloc] init]; @@ -52,15 +65,15 @@ void WiimoteScannerDarwin::FindWiimotes(std::vector& found_wiimotes, if ([bti start] != kIOReturnSuccess) { ERROR_LOG_FMT(WIIMOTE, "Unable to do Bluetooth discovery"); - [bth release]; [sbt release]; - btFailed = true; + + return; } do { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); - } while (!sbt->done && !stopScanning); + } while (!sbt->done && !m_stop_scanning); int found_devices = [[bti foundDevices] count]; @@ -86,15 +99,13 @@ void WiimoteScannerDarwin::FindWiimotes(std::vector& found_wiimotes, } } - [bth release]; [bti release]; [sbt release]; } bool WiimoteScannerDarwin::IsReady() const { - // TODO: only return true when a BT device is present - return true; + return m_host_controller != nil; } WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device) diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h b/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h index 05b6503b48..cbed1752e9 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h +++ b/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h @@ -4,13 +4,6 @@ #pragma once -// Work around an Apple bug: for some reason, IOBluetooth.h errors on -// inclusion in Mavericks, but only in Objective-C++ C++11 mode. I filed -// this as ; in the meantime... -#import -#undef NS_ENUM_AVAILABLE -#define NS_ENUM_AVAILABLE(...) -// end hack #import #include diff --git a/Source/Core/Core/HW/WiimoteReal/IOhidapi.h b/Source/Core/Core/HW/WiimoteReal/IOhidapi.h index d414acdf8a..2cc4505533 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOhidapi.h +++ b/Source/Core/Core/HW/WiimoteReal/IOhidapi.h @@ -38,7 +38,8 @@ public: ~WiimoteScannerHidapi(); bool IsReady() const override; void FindWiimotes(std::vector&, Wiimote*&) override; - void Update() override {} // not needed for hidapi + void Update() override {} // not needed for hidapi + void RequestStopSearching() override {} // not needed for hidapi }; } // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index 83d262ebeb..397cc0774e 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -545,6 +545,12 @@ void WiimoteScanner::StopThread() if (m_scan_thread_running.TestAndClear()) { SetScanMode(WiimoteScanMode::DO_NOT_SCAN); + + for (const auto& backend : m_backends) + { + backend->RequestStopSearching(); + } + m_scan_thread.join(); } } diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h index 701371d4bd..9756ff6204 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h @@ -1,4 +1,4 @@ -// Copyright 2008 Dolphin Emulator Project +// Copyright 2008 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. @@ -155,6 +155,8 @@ public: virtual void FindWiimotes(std::vector&, Wiimote*&) = 0; // function called when not looking for more Wiimotes virtual void Update() = 0; + // requests the backend to stop scanning if FindWiimotes is blocking + virtual void RequestStopSearching() = 0; }; enum class WiimoteScanMode