From f23326c66038b06ba43c342f7fce6d2f8ca4be73 Mon Sep 17 00:00:00 2001 From: pixl Date: Sat, 8 Jan 2022 22:32:49 -0500 Subject: [PATCH] Complete DeviceManager interface --- src/ipcgull | 2 +- src/logid/DeviceManager.cpp | 75 ++++++++++++++++++++++++++++--------- src/logid/DeviceManager.h | 12 +++++- src/logid/Receiver.cpp | 8 ++++ src/logid/Receiver.h | 7 +++- src/logid/logid.cpp | 2 +- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/src/ipcgull b/src/ipcgull index 73d837a..5f95b11 160000 --- a/src/ipcgull +++ b/src/ipcgull @@ -1 +1 @@ -Subproject commit 73d837add44f7524603557ee1819610dcc4a3037 +Subproject commit 5f95b1111ea2f3a6f8e2f0d60ccae12aebaa1a90 diff --git a/src/logid/DeviceManager.cpp b/src/logid/DeviceManager.cpp index 2cc806f..a1b7978 100644 --- a/src/logid/DeviceManager.cpp +++ b/src/logid/DeviceManager.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "DeviceManager.h" #include "Receiver.h" @@ -50,8 +51,8 @@ DeviceManager::DeviceManager(std::shared_ptr config, _device_node (ipcgull::node::make_root("devices")), _receiver_node (ipcgull::node::make_root("receivers")) { - _ipc_devices = _root_node->make_interface(); - _ipc_receivers = _root_node->make_interface(); + _ipc_devices = _root_node->make_interface(this); + _ipc_receivers = _root_node->make_interface(this); _device_node->add_server(_server); _receiver_node->add_server(_server); _root_node->add_server(_server); @@ -124,6 +125,7 @@ void DeviceManager::addDevice(std::string path) logPrintf(INFO, "Detected receiver at %s", path.c_str()); auto receiver = Receiver::make(path, _self.lock()); receiver->run(); + std::lock_guard lock(_map_lock); _receivers.emplace(path, receiver); _ipc_receivers->receiverAdded(receiver); } else { @@ -132,12 +134,14 @@ void DeviceManager::addDevice(std::string path) if(defaultExists) { auto device = Device::make(path, hidpp::DefaultDevice, _self.lock()); + std::lock_guard lock(_map_lock); _devices.emplace(path, device); _ipc_devices->deviceAdded(device); } else { try { auto device = Device::make(path, hidpp::CordedDevice, _self.lock()); + std::lock_guard lock(_map_lock); _devices.emplace(path, device); _ipc_devices->deviceAdded(device); } catch(hidpp10::Error &e) { @@ -167,8 +171,14 @@ void DeviceManager::removeExternalDevice(const std::shared_ptr &d) _ipc_devices->deviceRemoved(d); } +std::mutex& DeviceManager::mutex() const +{ + return _map_lock; +} + void DeviceManager::removeDevice(std::string path) { + std::lock_guard lock(_map_lock); auto receiver = _receivers.find(path); if(receiver != _receivers.end()) { @@ -185,55 +195,84 @@ void DeviceManager::removeDevice(std::string path) } } -DeviceManager::DevicesIPC::DevicesIPC() : ipcgull::interface( +DeviceManager::DevicesIPC::DevicesIPC(DeviceManager* manager) : +ipcgull::interface( "pizza.pixl.LogiOps.Devices", - {}, + { + {"Enumerate",{manager, &DeviceManager::listDevices,{"devices"}}} + }, {}, { - {"deviceAdded", + {"DeviceAdded", ipcgull::make_signal>( {"device"})}, - {"deviceRemoved", + {"DeviceRemoved", ipcgull::make_signal>( {"device"})} - } - ) + }) { } +std::vector> DeviceManager::listDevices() const +{ + std::lock_guard lock(_map_lock); + std::vector> devices; + for(auto& x : _devices) + devices.emplace_back(x.second); + for(auto& x : _receivers) { + for(auto& d : x.second->devices()) + devices.emplace_back(d.second); + } + + return devices; +} + +std::vector> DeviceManager::listReceivers() const +{ + std::lock_guard lock(_map_lock); + std::vector> receivers; + for(auto& x : _receivers) + receivers.emplace_back(x.second); + return receivers; +} + void DeviceManager::DevicesIPC::deviceAdded( const std::shared_ptr& d) { - emit_signal("deviceAdded", d); + emit_signal("DeviceAdded", d); } void DeviceManager::DevicesIPC::deviceRemoved( const std::shared_ptr& d) { - emit_signal("deviceRemoved", d); + emit_signal("DeviceRemoved", d); } -DeviceManager::ReceiversIPC::ReceiversIPC() : ipcgull::interface( +DeviceManager::ReceiversIPC::ReceiversIPC(DeviceManager* manager) : +ipcgull::interface( "pizza.pixl.LogiOps.Receivers", - {}, + { + {"Enumerate",{manager, &DeviceManager::listReceivers, + {"receivers"}}} + }, {}, { - {"receiverAdded", + {"ReceiverAdded", ipcgull::make_signal>( - {"device"})}, - {"receiverRemoved", + {"receiver"})}, + {"ReceiverRemoved", ipcgull::make_signal>( - {"device"})} + {"receiver"})} }) { } void DeviceManager::ReceiversIPC::receiverAdded( const std::shared_ptr& r) { - emit_signal("receiverAdded", r); + emit_signal("ReceiverAdded", r); } void DeviceManager::ReceiversIPC::receiverRemoved( const std::shared_ptr& r) { - emit_signal("receiverRemoved", r); + emit_signal("ReceiverRemoved", r); } int DeviceManager::newDeviceNickname() diff --git a/src/logid/DeviceManager.h b/src/logid/DeviceManager.h index 56e180e..8f67934 100644 --- a/src/logid/DeviceManager.h +++ b/src/logid/DeviceManager.h @@ -50,23 +50,29 @@ namespace logid void addExternalDevice(const std::shared_ptr& d); void removeExternalDevice(const std::shared_ptr& d); + + std::mutex& mutex() const; protected: void addDevice(std::string path) final; void removeDevice(std::string path) final; private: class DevicesIPC : public ipcgull::interface { public: - DevicesIPC(); + explicit DevicesIPC(DeviceManager* manager); void deviceAdded(const std::shared_ptr& d); void deviceRemoved(const std::shared_ptr& d); }; + [[nodiscard]] + std::vector> listDevices() const; class ReceiversIPC : public ipcgull::interface { public: - ReceiversIPC(); + explicit ReceiversIPC(DeviceManager* manager); void receiverAdded(const std::shared_ptr& r); void receiverRemoved(const std::shared_ptr& r); }; + [[nodiscard]] + std::vector> listReceivers() const; friend class _DeviceManager; DeviceManager(std::shared_ptr config, @@ -89,6 +95,8 @@ namespace logid std::map> _devices; std::map> _receivers; + mutable std::mutex _map_lock; + friend class DeviceNickname; friend class ReceiverNickname; diff --git a/src/logid/Receiver.cpp b/src/logid/Receiver.cpp index cfd2f8f..e4e487e 100644 --- a/src/logid/Receiver.cpp +++ b/src/logid/Receiver.cpp @@ -73,6 +73,10 @@ Receiver::Receiver(const std::string& path, { } +const Receiver::DeviceList& Receiver::devices() const { + return _devices; +} + Receiver::~Receiver() { if(auto manager = _manager.lock()) { @@ -124,6 +128,7 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) } auto device = Device::make(this, event.index, manager); + std::lock_guard manager_lock(manager->mutex()); _devices.emplace(event.index, device); manager->addExternalDevice(device); @@ -145,6 +150,9 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) void Receiver::removeDevice(hidpp::DeviceIndex index) { std::unique_lock lock(_devices_change); + std::unique_lock manager_lock; + if(auto manager = _manager.lock()) + manager_lock = std::unique_lock(manager->mutex()); auto device = _devices.find(index); if(device != _devices.end()) { if(auto manager = _manager.lock()) diff --git a/src/logid/Receiver.h b/src/logid/Receiver.h index 61c65c9..8022261 100644 --- a/src/logid/Receiver.h +++ b/src/logid/Receiver.h @@ -42,6 +42,9 @@ namespace logid public ipcgull::object { public: + typedef std::map> + DeviceList; + ~Receiver(); static std::shared_ptr make( @@ -49,6 +52,8 @@ namespace logid const std::shared_ptr& manager); const std::string& path() const; std::shared_ptr rawReceiver(); + + [[nodiscard]] const DeviceList& devices() const; protected: void addDevice(backend::hidpp::DeviceConnectionEvent event) override; void removeDevice(backend::hidpp::DeviceIndex index) override; @@ -59,7 +64,7 @@ namespace logid const std::shared_ptr& manager); std::mutex _devices_change; - std::map> _devices; + DeviceList _devices; std::string _path; std::weak_ptr _manager; diff --git a/src/logid/logid.cpp b/src/logid/logid.cpp index 340fece..b3ffcd6 100644 --- a/src/logid/logid.cpp +++ b/src/logid/logid.cpp @@ -159,7 +159,7 @@ int main(int argc, char** argv) std::shared_ptr virtual_input; auto server = ipcgull::make_server("pizza.pixl.LogiOps", - "/pizza/pixl/logiops", + "/pizza/pixl/LogiOps", ipcgull::IPCGULL_USER); std::thread( [server]() {