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.
This commit is contained in:
Léo Lam 2016-06-25 21:46:39 +02:00
parent afa202738e
commit 8678133e87
18 changed files with 80 additions and 60 deletions

View File

@ -218,8 +218,8 @@ void ControlDialog::UpdateListContents()
{ {
control_lbox->Clear(); control_lbox->Clear();
ciface::Core::Device* const dev = g_controller_interface.FindDevice(m_devq); const auto dev = g_controller_interface.FindDevice(m_devq);
if (dev) if (dev != nullptr)
{ {
if (control_reference->is_input) if (control_reference->is_input)
{ {
@ -493,8 +493,8 @@ void ControlDialog::DetectControl(wxCommandEvent& event)
wxButton* const btn = (wxButton*)event.GetEventObject(); wxButton* const btn = (wxButton*)event.GetEventObject();
const wxString lbl = btn->GetLabel(); const wxString lbl = btn->GetLabel();
ciface::Core::Device* const dev = g_controller_interface.FindDevice(m_devq); const auto dev = g_controller_interface.FindDevice(m_devq);
if (dev) if (dev != nullptr)
{ {
m_event_filter.BlockEvents(true); m_event_filter.BlockEvents(true);
btn->SetLabel(_("[ waiting ]")); 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 // This makes the "waiting" text work on Linux. true (only if needed) prevents crash on Windows
wxTheApp->Yield(true); 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 we got input, select it in the list
if (ctrl) if (ctrl)
@ -537,8 +538,8 @@ bool GamepadPage::DetectButton(ControlButton* button)
{ {
bool success = false; bool success = false;
// find device :/ // find device :/
ciface::Core::Device* const dev = g_controller_interface.FindDevice(controller->default_device); const auto dev = g_controller_interface.FindDevice(controller->default_device);
if (dev) if (dev != nullptr)
{ {
m_event_filter.BlockEvents(true); m_event_filter.BlockEvents(true);
button->SetLabel(_("[ waiting ]")); button->SetLabel(_("[ waiting ]"));
@ -547,7 +548,7 @@ bool GamepadPage::DetectButton(ControlButton* button)
wxTheApp->Yield(true); wxTheApp->Yield(true);
ciface::Core::Device::Control* const ctrl = 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 we got input, update expression and reference
if (ctrl) if (ctrl)
@ -724,16 +725,12 @@ void GamepadPage::DeleteProfile(wxCommandEvent&)
void InputConfigDialog::UpdateDeviceComboBox() void InputConfigDialog::UpdateDeviceComboBox()
{ {
ciface::Core::DeviceQualifier dq;
for (GamepadPage* page : m_padpages) for (GamepadPage* page : m_padpages)
{ {
page->device_cbox->Clear(); page->device_cbox->Clear();
for (ciface::Core::Device* d : g_controller_interface.Devices()) for (const std::string& device_string : g_controller_interface.GetAllDeviceStrings())
{ page->device_cbox->Append(StrToWxStr(device_string));
dq.FromDevice(d);
page->device_cbox->Append(StrToWxStr(dq.ToString()));
}
page->device_cbox->SetValue(StrToWxStr(page->controller->default_device.ToString())); page->device_cbox->SetValue(StrToWxStr(page->controller->default_device.ToString()));
} }

View File

@ -242,9 +242,10 @@ void ControllerEmu::LoadDefaults(const ControllerInterface& ciface)
IniFile::Section sec; IniFile::Section sec;
LoadConfig(&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(); UpdateDefaultDevice();
} }
} }

View File

@ -13,7 +13,7 @@ namespace Android
void Init() void Init()
{ {
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
g_controller_interface.AddDevice(new Touchscreen(i)); g_controller_interface.AddDevice(std::make_shared<Touchscreen>(i));
} }
// Touchscreens and stuff // Touchscreens and stuff

View File

@ -2,8 +2,10 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include <mutex>
#include "Common/Thread.h" #include "Common/Thread.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#ifdef CIFACE_USE_XINPUT #ifdef CIFACE_USE_XINPUT
#include "InputCommon/ControllerInterface/XInput/XInput.h" #include "InputCommon/ControllerInterface/XInput/XInput.h"
@ -106,14 +108,11 @@ void ControllerInterface::Shutdown()
std::lock_guard<std::mutex> lk(m_devices_mutex); std::lock_guard<std::mutex> lk(m_devices_mutex);
for (ciface::Core::Device* d : m_devices) for (const auto& d : m_devices)
{ {
// Set outputs to ZERO before destroying device // Set outputs to ZERO before destroying device
for (ciface::Core::Device::Output* o : d->Outputs()) for (ciface::Core::Device::Output* o : d->Outputs())
o->SetState(0); o->SetState(0);
// Delete device
delete d;
} }
m_devices.clear(); m_devices.clear();
@ -141,10 +140,10 @@ void ControllerInterface::Shutdown()
m_is_init = false; m_is_init = false;
} }
void ControllerInterface::AddDevice(ciface::Core::Device* device) void ControllerInterface::AddDevice(std::shared_ptr<ciface::Core::Device> device)
{ {
std::lock_guard<std::mutex> lk(m_devices_mutex); std::lock_guard<std::mutex> 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() void ControllerInterface::UpdateInput()
{ {
std::lock_guard<std::mutex> lk(m_devices_mutex); std::lock_guard<std::mutex> lk(m_devices_mutex);
for (ciface::Core::Device* d : m_devices) for (const auto& d : m_devices)
d->UpdateInput(); d->UpdateInput();
} }

View File

@ -6,7 +6,6 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <mutex>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -122,7 +121,7 @@ public:
void Initialize(void* const hwnd); void Initialize(void* const hwnd);
void Reinitialize(); void Reinitialize();
void Shutdown(); void Shutdown();
void AddDevice(ciface::Core::Device* device); void AddDevice(std::shared_ptr<ciface::Core::Device> device);
bool IsInit() const { return m_is_init; } bool IsInit() const { return m_is_init; }
void UpdateReference(ControlReference* control, void UpdateReference(ControlReference* control,
const ciface::Core::DeviceQualifier& default_device) const; const ciface::Core::DeviceQualifier& default_device) const;

View File

@ -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<Joystick>(js_device, name_counts[joystick.tszInstanceName]++);
// only add if it has some inputs/outputs // only add if it has some inputs/outputs
if (js->Inputs().size() || js->Outputs().size()) if (js->Inputs().size() || js->Outputs().size())
g_controller_interface.AddDevice(js); g_controller_interface.AddDevice(std::move(js));
else
delete js;
} }
else else
{ {

View File

@ -51,7 +51,7 @@ void InitKeyboardMouse(IDirectInput8* const idi8, HWND _hwnd)
SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) && SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) &&
SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) 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<KeyboardMouse>(kb_device, mo_device));
return; return;
} }

View File

@ -144,17 +144,45 @@ bool DeviceQualifier::operator==(const DeviceQualifier& devq) const
return false; return false;
} }
Device* DeviceContainer::FindDevice(const DeviceQualifier& devq) const std::shared_ptr<Device> DeviceContainer::FindDevice(const DeviceQualifier& devq) const
{ {
for (Device* d : m_devices) std::lock_guard<std::mutex> lk(m_devices_mutex);
for (const auto& d : m_devices)
{ {
if (devq == d) if (devq == d.get())
return d; return d;
} }
return nullptr; return nullptr;
} }
std::vector<std::string> DeviceContainer::GetAllDeviceStrings() const
{
std::lock_guard<std::mutex> lk(m_devices_mutex);
std::vector<std::string> 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<std::mutex> 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 Device::Input* DeviceContainer::FindInput(const std::string& name, const Device* def_dev) const
{ {
if (def_dev) if (def_dev)
@ -164,7 +192,8 @@ Device::Input* DeviceContainer::FindInput(const std::string& name, const Device*
return inp; return inp;
} }
for (Device* d : m_devices) std::lock_guard<std::mutex> lk(m_devices_mutex);
for (const auto& d : m_devices)
{ {
Device::Input* const i = d->FindInput(name); Device::Input* const i = d->FindInput(name);

View File

@ -164,12 +164,13 @@ public:
Device::Input* FindInput(const std::string& name, const Device* def_dev) const; Device::Input* FindInput(const std::string& name, const Device* def_dev) const;
Device::Output* FindOutput(const std::string& name, const Device* def_dev) const; Device::Output* FindOutput(const std::string& name, const Device* def_dev) const;
const std::vector<Device*>& Devices() const { return m_devices; } std::vector<std::string> GetAllDeviceStrings() const;
Device* FindDevice(const DeviceQualifier& devq) const; std::string GetDefaultDeviceString() const;
std::shared_ptr<Device> FindDevice(const DeviceQualifier& devq) const;
protected: protected:
std::mutex m_devices_mutex; mutable std::mutex m_devices_mutex;
std::vector<Device*> m_devices; std::vector<std::shared_ptr<Device>> m_devices;
}; };
} }
} }

View File

@ -333,7 +333,7 @@ public:
operator std::string() override { return OpName(op) + "(" + (std::string)(*inner) + ")"; } operator std::string() override { return OpName(op) + "(" + (std::string)(*inner) + ")"; }
}; };
Device* ControlFinder::FindDevice(ControlQualifier qualifier) std::shared_ptr<Device> ControlFinder::FindDevice(ControlQualifier qualifier)
{ {
if (qualifier.has_device) if (qualifier.has_device)
return container.FindDevice(qualifier.device_qualifier); return container.FindDevice(qualifier.device_qualifier);
@ -343,7 +343,7 @@ Device* ControlFinder::FindDevice(ControlQualifier qualifier)
Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) Device::Control* ControlFinder::FindControl(ControlQualifier qualifier)
{ {
Device* device = FindDevice(qualifier); const std::shared_ptr<Device> device = FindDevice(qualifier);
if (!device) if (!device)
return nullptr; return nullptr;

View File

@ -39,7 +39,7 @@ public:
Core::Device::Control* FindControl(ControlQualifier qualifier); Core::Device::Control* FindControl(ControlQualifier qualifier);
private: private:
Core::Device* FindDevice(ControlQualifier qualifier); std::shared_ptr<Core::Device> FindDevice(ControlQualifier qualifier);
const Core::DeviceContainer& container; const Core::DeviceContainer& container;
const Core::DeviceQualifier& default_device; const Core::DeviceQualifier& default_device;
bool is_input; bool is_input;

View File

@ -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 // Add a device if it's of a type we want
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
g_controller_interface.AddDevice( g_controller_interface.AddDevice(
new Keyboard(inIOHIDDeviceRef, name, kbd_name_counts[name]++, g_window)); std::make_shared<Keyboard>(inIOHIDDeviceRef, name, kbd_name_counts[name]++, g_window));
#if 0 #if 0
else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
@ -152,7 +152,8 @@ static void DeviceMatching_callback(void* inContext, IOReturn inResult, void* in
name, mouse_name_counts[name]++)); name, mouse_name_counts[name]++));
#endif #endif
else else
g_controller_interface.AddDevice(new Joystick(inIOHIDDeviceRef, name, joy_name_counts[name]++)); g_controller_interface.AddDevice(
std::make_shared<Joystick>(inIOHIDDeviceRef, name, joy_name_counts[name]++));
} }
void Init(void* window) void Init(void* window)

View File

@ -61,7 +61,7 @@ void Init()
int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK); int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0) if (fd < 0)
continue; continue;
g_controller_interface.AddDevice(new PipeDevice(fd, child.virtualName, found++)); g_controller_interface.AddDevice(std::make_shared<PipeDevice>(fd, child.virtualName, found++));
} }
} }

View File

@ -58,12 +58,10 @@ void Init()
SDL_Joystick* dev = SDL_JoystickOpen(i); SDL_Joystick* dev = SDL_JoystickOpen(i);
if (dev) if (dev)
{ {
Joystick* js = new Joystick(dev, i, name_counts[GetJoystickName(i)]++); auto js = std::make_shared<Joystick>(dev, i, name_counts[GetJoystickName(i)]++);
// only add if it has some inputs/outputs // only add if it has some inputs/outputs
if (js->Inputs().size() || js->Outputs().size()) if (js->Inputs().size() || js->Outputs().size())
g_controller_interface.AddDevice(js); g_controller_interface.AddDevice(std::move(js));
else
delete js;
} }
} }
} }

View File

@ -89,7 +89,7 @@ void Init()
XINPUT_CAPABILITIES caps; XINPUT_CAPABILITIES caps;
for (int i = 0; i != 4; ++i) for (int i = 0; i != 4; ++i)
if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps)) if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps))
g_controller_interface.AddDevice(new Device(caps, i)); g_controller_interface.AddDevice(std::make_shared<Device>(caps, i));
} }
void DeInit() void DeInit()

View File

@ -76,10 +76,12 @@ void Init(void* const hwnd)
{ {
current_master = &all_masters[i]; current_master = &all_masters[i];
if (current_master->use == XIMasterPointer) if (current_master->use == XIMasterPointer)
{
// Since current_master is a master pointer, its attachment must // Since current_master is a master pointer, its attachment must
// be a master keyboard. // be a master keyboard.
g_controller_interface.AddDevice(new KeyboardMouse( g_controller_interface.AddDevice(std::make_shared<KeyboardMouse>(
(Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment)); (Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment));
}
} }
XCloseDisplay(dpy); XCloseDisplay(dpy);

View File

@ -13,7 +13,7 @@ namespace Xlib
{ {
void Init(void* const hwnd) void Init(void* const hwnd)
{ {
g_controller_interface.AddDevice(new KeyboardMouse((Window)hwnd)); g_controller_interface.AddDevice(std::make_shared<KeyboardMouse>((Window)hwnd));
} }
KeyboardMouse::KeyboardMouse(Window window) : m_window(window) KeyboardMouse::KeyboardMouse(Window window) : m_window(window)

View File

@ -68,18 +68,13 @@ void Init()
// Unfortunately udev gives us no way to filter out the non event device interfaces. // 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. // So we open it and see if it works with evdev ioctls or not.
std::string name = GetName(devnode); std::string name = GetName(devnode);
evdevDevice* input = new evdevDevice(devnode, name_counts[name]++); auto input = std::make_shared<evdevDevice>(devnode, name_counts[name]++);
if (input->IsInteresting()) if (input->IsInteresting())
{ {
g_controller_interface.AddDevice(input); g_controller_interface.AddDevice(std::move(input));
num_controllers++; 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); udev_device_unref(dev);
} }