From 8678133e8746fdc20f7d012005ebf2db370ddccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 25 Jun 2016 21:46:39 +0200 Subject: [PATCH] ControllerInterface: Switch to std::shared_ptr Small cleanup by using std::shared_ptr and getting rid of ciface.Devices() which just returned the m_devices (which defeats the point of making m_devices protected). Incidentally, this should make the code safer when we have different threads accessing devices in the future (for hotplug?). A lot of code use Device references directly so there is no easy way to remove FindDevice() and make those unique_ptrs. --- Source/Core/DolphinWX/InputConfigDiag.cpp | 25 ++++++------- Source/Core/InputCommon/ControllerEmu.cpp | 5 ++- .../ControllerInterface/Android/Android.cpp | 2 +- .../ControllerInterface.cpp | 15 ++++---- .../ControllerInterface/ControllerInterface.h | 3 +- .../DInput/DInputJoystick.cpp | 6 +-- .../DInput/DInputKeyboardMouse.cpp | 2 +- .../ControllerInterface/Device.cpp | 37 +++++++++++++++++-- .../InputCommon/ControllerInterface/Device.h | 9 +++-- .../ControllerInterface/ExpressionParser.cpp | 4 +- .../ControllerInterface/ExpressionParser.h | 2 +- .../ControllerInterface/OSX/OSX.mm | 5 ++- .../ControllerInterface/Pipes/Pipes.cpp | 2 +- .../ControllerInterface/SDL/SDL.cpp | 6 +-- .../ControllerInterface/XInput/XInput.cpp | 2 +- .../ControllerInterface/Xlib/XInput2.cpp | 4 +- .../ControllerInterface/Xlib/Xlib.cpp | 2 +- .../ControllerInterface/evdev/evdev.cpp | 9 +---- 18 files changed, 80 insertions(+), 60 deletions(-) diff --git a/Source/Core/DolphinWX/InputConfigDiag.cpp b/Source/Core/DolphinWX/InputConfigDiag.cpp index 46e79413ad..28e07023b8 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/InputConfigDiag.cpp @@ -218,8 +218,8 @@ void ControlDialog::UpdateListContents() { control_lbox->Clear(); - ciface::Core::Device* const dev = g_controller_interface.FindDevice(m_devq); - if (dev) + const auto dev = g_controller_interface.FindDevice(m_devq); + if (dev != nullptr) { if (control_reference->is_input) { @@ -493,8 +493,8 @@ void ControlDialog::DetectControl(wxCommandEvent& event) wxButton* const btn = (wxButton*)event.GetEventObject(); const wxString lbl = btn->GetLabel(); - ciface::Core::Device* const dev = g_controller_interface.FindDevice(m_devq); - if (dev) + const auto dev = g_controller_interface.FindDevice(m_devq); + if (dev != nullptr) { m_event_filter.BlockEvents(true); btn->SetLabel(_("[ waiting ]")); @@ -502,7 +502,8 @@ void ControlDialog::DetectControl(wxCommandEvent& event) // This makes the "waiting" text work on Linux. true (only if needed) prevents crash on Windows wxTheApp->Yield(true); - ciface::Core::Device::Control* const ctrl = control_reference->Detect(DETECT_WAIT_TIME, dev); + ciface::Core::Device::Control* const ctrl = + control_reference->Detect(DETECT_WAIT_TIME, dev.get()); // if we got input, select it in the list if (ctrl) @@ -537,8 +538,8 @@ bool GamepadPage::DetectButton(ControlButton* button) { bool success = false; // find device :/ - ciface::Core::Device* const dev = g_controller_interface.FindDevice(controller->default_device); - if (dev) + const auto dev = g_controller_interface.FindDevice(controller->default_device); + if (dev != nullptr) { m_event_filter.BlockEvents(true); button->SetLabel(_("[ waiting ]")); @@ -547,7 +548,7 @@ bool GamepadPage::DetectButton(ControlButton* button) wxTheApp->Yield(true); ciface::Core::Device::Control* const ctrl = - button->control_reference->Detect(DETECT_WAIT_TIME, dev); + button->control_reference->Detect(DETECT_WAIT_TIME, dev.get()); // if we got input, update expression and reference if (ctrl) @@ -724,16 +725,12 @@ void GamepadPage::DeleteProfile(wxCommandEvent&) void InputConfigDialog::UpdateDeviceComboBox() { - ciface::Core::DeviceQualifier dq; for (GamepadPage* page : m_padpages) { page->device_cbox->Clear(); - for (ciface::Core::Device* d : g_controller_interface.Devices()) - { - dq.FromDevice(d); - page->device_cbox->Append(StrToWxStr(dq.ToString())); - } + for (const std::string& device_string : g_controller_interface.GetAllDeviceStrings()) + page->device_cbox->Append(StrToWxStr(device_string)); page->device_cbox->SetValue(StrToWxStr(page->controller->default_device.ToString())); } diff --git a/Source/Core/InputCommon/ControllerEmu.cpp b/Source/Core/InputCommon/ControllerEmu.cpp index 4d333e1d23..54d25748ad 100644 --- a/Source/Core/InputCommon/ControllerEmu.cpp +++ b/Source/Core/InputCommon/ControllerEmu.cpp @@ -242,9 +242,10 @@ void ControllerEmu::LoadDefaults(const ControllerInterface& ciface) IniFile::Section sec; LoadConfig(&sec); - if (ciface.Devices().size()) + const std::string& default_device_string = g_controller_interface.GetDefaultDeviceString(); + if (!default_device_string.empty()) { - default_device.FromDevice(ciface.Devices()[0]); + default_device.FromString(default_device_string); UpdateDefaultDevice(); } } diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index f6957e3ca1..e36e314294 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -13,7 +13,7 @@ namespace Android void Init() { for (int i = 0; i < 8; ++i) - g_controller_interface.AddDevice(new Touchscreen(i)); + g_controller_interface.AddDevice(std::make_shared(i)); } // Touchscreens and stuff diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index b36387162d..cbf2c4dfbb 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -2,8 +2,10 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "InputCommon/ControllerInterface/ControllerInterface.h" +#include + #include "Common/Thread.h" +#include "InputCommon/ControllerInterface/ControllerInterface.h" #ifdef CIFACE_USE_XINPUT #include "InputCommon/ControllerInterface/XInput/XInput.h" @@ -106,14 +108,11 @@ void ControllerInterface::Shutdown() std::lock_guard lk(m_devices_mutex); - for (ciface::Core::Device* d : m_devices) + for (const auto& d : m_devices) { // Set outputs to ZERO before destroying device for (ciface::Core::Device::Output* o : d->Outputs()) o->SetState(0); - - // Delete device - delete d; } m_devices.clear(); @@ -141,10 +140,10 @@ void ControllerInterface::Shutdown() m_is_init = false; } -void ControllerInterface::AddDevice(ciface::Core::Device* device) +void ControllerInterface::AddDevice(std::shared_ptr device) { std::lock_guard lk(m_devices_mutex); - m_devices.push_back(device); + m_devices.emplace_back(std::move(device)); } // @@ -155,7 +154,7 @@ void ControllerInterface::AddDevice(ciface::Core::Device* device) void ControllerInterface::UpdateInput() { std::lock_guard lk(m_devices_mutex); - for (ciface::Core::Device* d : m_devices) + for (const auto& d : m_devices) d->UpdateInput(); } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index 2571e5f3ab..2f4212ba85 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -122,7 +121,7 @@ public: void Initialize(void* const hwnd); void Reinitialize(); void Shutdown(); - void AddDevice(ciface::Core::Device* device); + void AddDevice(std::shared_ptr device); bool IsInit() const { return m_is_init; } void UpdateReference(ControlReference* control, const ciface::Core::DeviceQualifier& default_device) const; diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp index ea059fde73..ecd1bf1d40 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp @@ -58,12 +58,10 @@ void InitJoystick(IDirectInput8* const idi8, HWND hwnd) } } - Joystick* js = new Joystick(/*&*i, */ js_device, name_counts[joystick.tszInstanceName]++); + auto js = std::make_shared(js_device, name_counts[joystick.tszInstanceName]++); // only add if it has some inputs/outputs if (js->Inputs().size() || js->Outputs().size()) - g_controller_interface.AddDevice(js); - else - delete js; + g_controller_interface.AddDevice(std::move(js)); } else { diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index fc02238980..2ee0477653 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -51,7 +51,7 @@ void InitKeyboardMouse(IDirectInput8* const idi8, HWND _hwnd) SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) && SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) { - g_controller_interface.AddDevice(new KeyboardMouse(kb_device, mo_device)); + g_controller_interface.AddDevice(std::make_shared(kb_device, mo_device)); return; } diff --git a/Source/Core/InputCommon/ControllerInterface/Device.cpp b/Source/Core/InputCommon/ControllerInterface/Device.cpp index 7a3b8ac845..e47b04de99 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Device.cpp @@ -144,17 +144,45 @@ bool DeviceQualifier::operator==(const DeviceQualifier& devq) const return false; } -Device* DeviceContainer::FindDevice(const DeviceQualifier& devq) const +std::shared_ptr DeviceContainer::FindDevice(const DeviceQualifier& devq) const { - for (Device* d : m_devices) + std::lock_guard lk(m_devices_mutex); + for (const auto& d : m_devices) { - if (devq == d) + if (devq == d.get()) return d; } return nullptr; } +std::vector DeviceContainer::GetAllDeviceStrings() const +{ + std::lock_guard lk(m_devices_mutex); + + std::vector device_strings; + DeviceQualifier device_qualifier; + + for (const auto& d : m_devices) + { + device_qualifier.FromDevice(d.get()); + device_strings.emplace_back(device_qualifier.ToString()); + } + + return device_strings; +} + +std::string DeviceContainer::GetDefaultDeviceString() const +{ + std::lock_guard lk(m_devices_mutex); + if (m_devices.empty()) + return ""; + + DeviceQualifier device_qualifier; + device_qualifier.FromDevice(m_devices[0].get()); + return device_qualifier.ToString(); +} + Device::Input* DeviceContainer::FindInput(const std::string& name, const Device* def_dev) const { if (def_dev) @@ -164,7 +192,8 @@ Device::Input* DeviceContainer::FindInput(const std::string& name, const Device* return inp; } - for (Device* d : m_devices) + std::lock_guard lk(m_devices_mutex); + for (const auto& d : m_devices) { Device::Input* const i = d->FindInput(name); diff --git a/Source/Core/InputCommon/ControllerInterface/Device.h b/Source/Core/InputCommon/ControllerInterface/Device.h index c3cddb3a79..23c499ec9d 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.h +++ b/Source/Core/InputCommon/ControllerInterface/Device.h @@ -164,12 +164,13 @@ public: Device::Input* FindInput(const std::string& name, const Device* def_dev) const; Device::Output* FindOutput(const std::string& name, const Device* def_dev) const; - const std::vector& Devices() const { return m_devices; } - Device* FindDevice(const DeviceQualifier& devq) const; + std::vector GetAllDeviceStrings() const; + std::string GetDefaultDeviceString() const; + std::shared_ptr FindDevice(const DeviceQualifier& devq) const; protected: - std::mutex m_devices_mutex; - std::vector m_devices; + mutable std::mutex m_devices_mutex; + std::vector> m_devices; }; } } diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index a87bdf8d35..7c916d108d 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -333,7 +333,7 @@ public: operator std::string() override { return OpName(op) + "(" + (std::string)(*inner) + ")"; } }; -Device* ControlFinder::FindDevice(ControlQualifier qualifier) +std::shared_ptr ControlFinder::FindDevice(ControlQualifier qualifier) { if (qualifier.has_device) return container.FindDevice(qualifier.device_qualifier); @@ -343,7 +343,7 @@ Device* ControlFinder::FindDevice(ControlQualifier qualifier) Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) { - Device* device = FindDevice(qualifier); + const std::shared_ptr device = FindDevice(qualifier); if (!device) return nullptr; diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h index 6894c1924e..80904634e4 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h @@ -39,7 +39,7 @@ public: Core::Device::Control* FindControl(ControlQualifier qualifier); private: - Core::Device* FindDevice(ControlQualifier qualifier); + std::shared_ptr FindDevice(ControlQualifier qualifier); const Core::DeviceContainer& container; const Core::DeviceQualifier& default_device; bool is_input; diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm index ea9723c6b9..48580cf98b 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm @@ -144,7 +144,7 @@ static void DeviceMatching_callback(void* inContext, IOReturn inResult, void* in // Add a device if it's of a type we want if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) g_controller_interface.AddDevice( - new Keyboard(inIOHIDDeviceRef, name, kbd_name_counts[name]++, g_window)); + std::make_shared(inIOHIDDeviceRef, name, kbd_name_counts[name]++, g_window)); #if 0 else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) @@ -152,7 +152,8 @@ static void DeviceMatching_callback(void* inContext, IOReturn inResult, void* in name, mouse_name_counts[name]++)); #endif else - g_controller_interface.AddDevice(new Joystick(inIOHIDDeviceRef, name, joy_name_counts[name]++)); + g_controller_interface.AddDevice( + std::make_shared(inIOHIDDeviceRef, name, joy_name_counts[name]++)); } void Init(void* window) diff --git a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp index fc89d8a1e6..b361fee279 100644 --- a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp @@ -61,7 +61,7 @@ void Init() int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK); if (fd < 0) continue; - g_controller_interface.AddDevice(new PipeDevice(fd, child.virtualName, found++)); + g_controller_interface.AddDevice(std::make_shared(fd, child.virtualName, found++)); } } diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp index 870f0387d7..a31abd3055 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp @@ -58,12 +58,10 @@ void Init() SDL_Joystick* dev = SDL_JoystickOpen(i); if (dev) { - Joystick* js = new Joystick(dev, i, name_counts[GetJoystickName(i)]++); + auto js = std::make_shared(dev, i, name_counts[GetJoystickName(i)]++); // only add if it has some inputs/outputs if (js->Inputs().size() || js->Outputs().size()) - g_controller_interface.AddDevice(js); - else - delete js; + g_controller_interface.AddDevice(std::move(js)); } } } diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp index 982764d4b4..c36c3126f6 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp @@ -89,7 +89,7 @@ void Init() XINPUT_CAPABILITIES caps; for (int i = 0; i != 4; ++i) if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps)) - g_controller_interface.AddDevice(new Device(caps, i)); + g_controller_interface.AddDevice(std::make_shared(caps, i)); } void DeInit() diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index d46f1cf4f6..c7c2e74242 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -76,10 +76,12 @@ void Init(void* const hwnd) { current_master = &all_masters[i]; if (current_master->use == XIMasterPointer) + { // Since current_master is a master pointer, its attachment must // be a master keyboard. - g_controller_interface.AddDevice(new KeyboardMouse( + g_controller_interface.AddDevice(std::make_shared( (Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment)); + } } XCloseDisplay(dpy); diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp index a7d94bbcd0..fd5cda04ec 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp @@ -13,7 +13,7 @@ namespace Xlib { void Init(void* const hwnd) { - g_controller_interface.AddDevice(new KeyboardMouse((Window)hwnd)); + g_controller_interface.AddDevice(std::make_shared((Window)hwnd)); } KeyboardMouse::KeyboardMouse(Window window) : m_window(window) diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp index 5da77e585a..658a442420 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp @@ -68,18 +68,13 @@ void Init() // Unfortunately udev gives us no way to filter out the non event device interfaces. // So we open it and see if it works with evdev ioctls or not. std::string name = GetName(devnode); - evdevDevice* input = new evdevDevice(devnode, name_counts[name]++); + auto input = std::make_shared(devnode, name_counts[name]++); if (input->IsInteresting()) { - g_controller_interface.AddDevice(input); + g_controller_interface.AddDevice(std::move(input)); num_controllers++; } - else - { - // Either it wasn't a evdev device, or it didn't have at least 8 buttons or two axis. - delete input; - } } udev_device_unref(dev); }