void ControllerInterface::AddDevice(std::shared_ptr<ciface::Core::Device> device) { { std::lock_guard<std::mutex> lk(m_devices_mutex); // Try to find an ID for this device int id = 0; while (true) { const auto it = std::find_if(m_devices.begin(), m_devices.end(), [&device, &id](const auto& d) { return d->GetSource() == device->GetSource() && d->GetName() == device->GetName() && d->GetId() == id; }); if (it == m_devices.end()) // no device with the same name with this ID, so we can use it break; else id++; } device->SetId(id); NOTICE_LOG(SERIALINTERFACE, "Added device: %s", device->GetQualifiedName().c_str()); m_devices.emplace_back(std::move(device)); } if (!m_is_populating_devices) InvokeDevicesChangedCallbacks(); }
// Remove all devices and call library cleanup functions void ControllerInterface::Shutdown() { if (!m_is_init) return; // Prevent additional devices from being added during shutdown. m_is_init = false; { std::lock_guard<std::mutex> lk(m_devices_mutex); for (const auto& d : m_devices) { // Set outputs to ZERO before destroying device for (ciface::Core::Device::Output* o : d->Outputs()) o->SetState(0); } m_devices.clear(); } // This will update control references so shared_ptr<Device>s are freed up // BEFORE we shutdown the backends. InvokeDevicesChangedCallbacks(); #ifdef CIFACE_USE_XINPUT ciface::XInput::DeInit(); #endif #ifdef CIFACE_USE_DINPUT // nothing needed #endif #ifdef CIFACE_USE_XLIB // nothing needed #endif #ifdef CIFACE_USE_OSX ciface::OSX::DeInit(); ciface::Quartz::DeInit(); #endif #ifdef CIFACE_USE_SDL ciface::SDL::DeInit(); #endif #ifdef CIFACE_USE_ANDROID // nothing needed #endif #ifdef CIFACE_USE_EVDEV ciface::evdev::Shutdown(); #endif }
void ControllerInterface::RefreshDevices() { if (!m_is_init) return; { std::lock_guard<std::mutex> lk(m_devices_mutex); m_devices.clear(); } m_is_populating_devices = true; #ifdef CIFACE_USE_DINPUT if (m_wsi.type == WindowSystemType::Windows) ciface::DInput::PopulateDevices(reinterpret_cast<HWND>(m_wsi.render_surface)); #endif #ifdef CIFACE_USE_XINPUT ciface::XInput::PopulateDevices(); #endif #ifdef CIFACE_USE_XLIB if (m_wsi.type == WindowSystemType::X11) ciface::XInput2::PopulateDevices(m_wsi.render_surface); #endif #ifdef CIFACE_USE_OSX if (m_wsi.type == WindowSystemType::MacOS) { ciface::OSX::PopulateDevices(m_wsi.render_surface); ciface::Quartz::PopulateDevices(m_wsi.render_surface); } #endif #ifdef CIFACE_USE_SDL ciface::SDL::PopulateDevices(); #endif #ifdef CIFACE_USE_ANDROID ciface::Android::PopulateDevices(); #endif #ifdef CIFACE_USE_EVDEV ciface::evdev::PopulateDevices(); #endif #ifdef CIFACE_USE_PIPES ciface::Pipes::PopulateDevices(); #endif m_is_populating_devices = false; InvokeDevicesChangedCallbacks(); }
void ControllerInterface::RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback) { { std::lock_guard<std::mutex> lk(m_devices_mutex); auto it = std::remove_if(m_devices.begin(), m_devices.end(), [&callback](const auto& dev) { if (callback(dev.get())) { NOTICE_LOG(SERIALINTERFACE, "Removed device: %s", dev->GetQualifiedName().c_str()); return true; } return false; }); m_devices.erase(it, m_devices.end()); } if (!m_is_populating_devices) InvokeDevicesChangedCallbacks(); }