From f76d9dfaf5361b78911e349d5f09ea822fd48e29 Mon Sep 17 00:00:00 2001 From: pixl Date: Sat, 5 Mar 2022 21:32:12 -0500 Subject: [PATCH] Use event handler ids for hidpp::Device --- src/logid/backend/dj/Receiver.h | 4 +- src/logid/backend/hidpp/Device.cpp | 25 ++++----- src/logid/backend/hidpp/Device.h | 12 ++-- .../backend/hidpp20/features/ThumbWheel.cpp | 3 +- .../backend/hidpp20/features/ThumbWheel.h | 3 +- src/logid/backend/raw/RawDevice.cpp | 4 +- src/logid/features/DeviceStatus.cpp | 40 ++++++------- src/logid/features/DeviceStatus.h | 2 + src/logid/features/HiresScroll.cpp | 28 +++++----- src/logid/features/HiresScroll.h | 2 + src/logid/features/RemapButton.cpp | 56 ++++++++++--------- src/logid/features/RemapButton.h | 1 + src/logid/features/ThumbWheel.cpp | 29 +++++----- src/logid/features/ThumbWheel.h | 2 + 14 files changed, 107 insertions(+), 104 deletions(-) diff --git a/src/logid/backend/dj/Receiver.h b/src/logid/backend/dj/Receiver.h index 37c0262..732c16b 100644 --- a/src/logid/backend/dj/Receiver.h +++ b/src/logid/backend/dj/Receiver.h @@ -31,8 +31,8 @@ namespace dj { struct EventHandler { - std::function condition; - std::function callback; + std::function condition; + std::function callback; }; class InvalidReceiver : public std::exception diff --git a/src/logid/backend/hidpp/Device.cpp b/src/logid/backend/hidpp/Device.cpp index 418cbd4..46822e6 100644 --- a/src/logid/backend/hidpp/Device.cpp +++ b/src/logid/backend/hidpp/Device.cpp @@ -213,23 +213,17 @@ Device::~Device() _raw_device->removeEventHandler(_raw_handler); } -void Device::addEventHandler(const std::string& nickname, - const std::shared_ptr& handler) +Device::EvHandlerId Device::addEventHandler(EventHandler handler) { - assert(_event_handlers.find(nickname) == _event_handlers.end()); - - _event_handlers.emplace(nickname, handler); + std::lock_guard lock(_event_handler_lock); + _event_handlers.emplace_front(std::move(handler)); + return _event_handlers.cbegin(); } -void Device::removeEventHandler(const std::string& nickname) +void Device::removeEventHandler(EvHandlerId id) { - _event_handlers.erase(nickname); -} - -const std::map>& - Device::eventHandlers() -{ - return _event_handlers; + std::lock_guard lock(_event_handler_lock); + _event_handlers.erase(id); } void Device::handleEvent(Report& report) @@ -237,9 +231,10 @@ void Device::handleEvent(Report& report) if(responseReport(report)) return; + std::lock_guard lock(_event_handler_lock); for(auto& handler : _event_handlers) - if(handler.second->condition(report)) - handler.second->callback(report); + if(handler.condition(report)) + handler.callback(report); } Report Device::sendReport(const Report &report) diff --git a/src/logid/backend/hidpp/Device.h b/src/logid/backend/hidpp/Device.h index 4b63f41..d8f1b6f 100644 --- a/src/logid/backend/hidpp/Device.h +++ b/src/logid/backend/hidpp/Device.h @@ -46,6 +46,8 @@ namespace hidpp class Device { public: + typedef std::list::const_iterator EvHandlerId; + class InvalidDevice : std::exception { public: @@ -80,11 +82,8 @@ namespace hidpp std::string name() const; uint16_t pid() const; - void addEventHandler(const std::string& nickname, - const std::shared_ptr& handler); - void removeEventHandler(const std::string& nickname); - const std::map>& - eventHandlers(); + EvHandlerId addEventHandler(EventHandler handler); + void removeEventHandler(EvHandlerId id); virtual Report sendReport(const Report& report); void sendReportNoResponse(Report report); @@ -117,7 +116,8 @@ namespace hidpp std::mutex _slot_lock; std::optional _report_slot; - std::map> _event_handlers; + std::mutex _event_handler_lock; + std::list _event_handlers; }; } } } diff --git a/src/logid/backend/hidpp20/features/ThumbWheel.cpp b/src/logid/backend/hidpp20/features/ThumbWheel.cpp index a2d6c60..a4262ea 100644 --- a/src/logid/backend/hidpp20/features/ThumbWheel.cpp +++ b/src/logid/backend/hidpp20/features/ThumbWheel.cpp @@ -69,7 +69,8 @@ ThumbWheel::ThumbwheelStatus ThumbWheel::setStatus(bool divert, bool invert) return status; } -ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(hidpp::Report& report) +ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent( + const hidpp::Report& report) { assert(report.function() == Event); ThumbwheelEvent event{}; diff --git a/src/logid/backend/hidpp20/features/ThumbWheel.h b/src/logid/backend/hidpp20/features/ThumbWheel.h index 7079f76..b66dc2a 100644 --- a/src/logid/backend/hidpp20/features/ThumbWheel.h +++ b/src/logid/backend/hidpp20/features/ThumbWheel.h @@ -86,7 +86,8 @@ namespace hidpp20 ThumbwheelStatus setStatus(bool divert, bool invert); - ThumbwheelEvent thumbwheelEvent(hidpp::Report& report); + [[nodiscard]] ThumbwheelEvent thumbwheelEvent( + const hidpp::Report& report); }; }}} diff --git a/src/logid/backend/raw/RawDevice.cpp b/src/logid/backend/raw/RawDevice.cpp index 9d58982..86fcaf0 100644 --- a/src/logid/backend/raw/RawDevice.cpp +++ b/src/logid/backend/raw/RawDevice.cpp @@ -174,14 +174,14 @@ void RawDevice::sendReport(const std::vector& report) RawDevice::EvHandlerId RawDevice::addEventHandler(RawEventHandler handler) { - std::unique_lock lock(_event_handler_lock); + std::lock_guard lock(_event_handler_lock); _event_handlers.emplace_front(std::move(handler)); return _event_handlers.cbegin(); } void RawDevice::removeEventHandler(RawDevice::EvHandlerId id) { - std::unique_lock lock(_event_handler_lock); + std::lock_guard lock(_event_handler_lock); _event_handlers.erase(id); } diff --git a/src/logid/features/DeviceStatus.cpp b/src/logid/features/DeviceStatus.cpp index 0757cd8..08dc093 100644 --- a/src/logid/features/DeviceStatus.cpp +++ b/src/logid/features/DeviceStatus.cpp @@ -18,8 +18,6 @@ #include "DeviceStatus.h" #include "../util/task.h" -#define EVENTHANDLER_NAME "devicestatus" - using namespace logid::features; using namespace logid::backend; @@ -41,6 +39,12 @@ DeviceStatus::DeviceStatus(logid::Device *dev) : DeviceFeature(dev) } } +DeviceStatus::~DeviceStatus() noexcept +{ + if(_ev_handler.has_value()) + _device->hidpp20().removeEventHandler(_ev_handler.value()); +} + void DeviceStatus::configure() { // Do nothing @@ -48,23 +52,19 @@ void DeviceStatus::configure() void DeviceStatus::listen() { - if(_device->hidpp20().eventHandlers().find(EVENTHANDLER_NAME) == - _device->hidpp20().eventHandlers().end()) { - auto handler = std::make_shared(); - handler->condition = [index=_wireless_device_status->featureIndex()]( - const hidpp::Report& report)->bool { - return report.feature() == index && report.function() == - hidpp20::WirelessDeviceStatus::StatusBroadcast; - }; - - handler->callback = [dev=this->_device]( - const hidpp::Report& report)->void { - auto event = hidpp20::WirelessDeviceStatus::statusBroadcastEvent( - report); - if(event.reconfNeeded) - spawn_task( [dev](){ dev->wakeup(); }); - }; - - _device->hidpp20().addEventHandler(EVENTHANDLER_NAME, handler); + if(!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler({ + [index=_wireless_device_status->featureIndex()]( + const hidpp::Report& report)->bool { + return report.feature() == index && report.function() == + hidpp20::WirelessDeviceStatus::StatusBroadcast; + }, + [dev=this->_device](const hidpp::Report& report) { + auto event = + hidpp20::WirelessDeviceStatus::statusBroadcastEvent(report); + if(event.reconfNeeded) + spawn_task( [dev](){ dev->wakeup(); }); + } + }); } } \ No newline at end of file diff --git a/src/logid/features/DeviceStatus.h b/src/logid/features/DeviceStatus.h index 985f8fd..abe23b6 100644 --- a/src/logid/features/DeviceStatus.h +++ b/src/logid/features/DeviceStatus.h @@ -30,9 +30,11 @@ namespace features { public: explicit DeviceStatus(Device* dev); + ~DeviceStatus(); virtual void configure(); virtual void listen(); private: + std::optional _ev_handler; std::shared_ptr _wireless_device_status; }; diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index bbfd7d4..1a9ca47 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -70,7 +70,8 @@ HiresScroll::HiresScroll(Device *dev) : DeviceFeature(dev), HiresScroll::~HiresScroll() { - _device->hidpp20().removeEventHandler(MOVE_EVENTHANDLER_NAME); + if(_ev_handler.has_value()) + _device->hidpp20().removeEventHandler(_ev_handler.value()); } void HiresScroll::configure() @@ -83,20 +84,17 @@ void HiresScroll::configure() void HiresScroll::listen() { - if(_device->hidpp20().eventHandlers().find(MOVE_EVENTHANDLER_NAME) == - _device->hidpp20().eventHandlers().end()) { - auto handler = std::make_shared(); - handler->condition = [index=_hires_scroll->featureIndex()] - (hidpp::Report& report)->bool { - return (report.feature() == index) && (report.function() == - hidpp20::HiresScroll::WheelMovement); - }; - - handler->callback = [this](hidpp::Report& report)->void { - this->_handleScroll(_hires_scroll->wheelMovementEvent(report)); - }; - - _device->hidpp20().addEventHandler(MOVE_EVENTHANDLER_NAME, handler); + if(!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler({ + [index=_hires_scroll->featureIndex()]( + const hidpp::Report& report)->bool { + return (report.feature() == index) && (report.function() == + hidpp20::HiresScroll::WheelMovement); + }, + [this](const hidpp::Report& report) { + _handleScroll(_hires_scroll->wheelMovementEvent(report)); + } + }); } } diff --git a/src/logid/features/HiresScroll.h b/src/logid/features/HiresScroll.h index 0ebdc4d..15312b3 100644 --- a/src/logid/features/HiresScroll.h +++ b/src/logid/features/HiresScroll.h @@ -36,6 +36,8 @@ namespace features uint8_t getMode(); void setMode(uint8_t mode); private: + std::optional _ev_handler; + void _makeAction(std::shared_ptr& gesture, std::optional& config, const std::string& direction); diff --git a/src/logid/features/RemapButton.cpp b/src/logid/features/RemapButton.cpp index c8b5034..5ac58ef 100644 --- a/src/logid/features/RemapButton.cpp +++ b/src/logid/features/RemapButton.cpp @@ -28,8 +28,6 @@ using namespace logid::actions; #define HIDPP20_REPROG_REBIND (hidpp20::ReprogControls::ChangeTemporaryDivert \ | hidpp20::ReprogControls::ChangeRawXYDivert) -#define EVENTHANDLER_NAME "REMAP_BUTTON" - RemapButton::RemapButton(Device *dev): DeviceFeature(dev), _config (dev->activeProfile().buttons), _ipc_node (dev->ipcNode()->make_child("buttons")) @@ -99,7 +97,8 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev), RemapButton::~RemapButton() { - _device->hidpp20().removeEventHandler(EVENTHANDLER_NAME); + if(_ev_handler.has_value()) + _device->hidpp20().removeEventHandler(_ev_handler.value()); } void RemapButton::configure() @@ -110,30 +109,35 @@ void RemapButton::configure() void RemapButton::listen() { - if(_device->hidpp20().eventHandlers().find(EVENTHANDLER_NAME) == - _device->hidpp20().eventHandlers().end()) { - auto handler = std::make_shared(); - handler->condition = [index=_reprog_controls->featureIndex()] - (hidpp::Report& report)->bool { - return (report.feature() == index) && ((report.function() == - hidpp20::ReprogControls::DivertedButtonEvent) || (report - .function() == hidpp20::ReprogControls::DivertedRawXYEvent)); - }; - - handler->callback = [this](hidpp::Report& report)->void { - if(report.function() == - hidpp20::ReprogControls::DivertedButtonEvent) - this->_buttonEvent(_reprog_controls->divertedButtonEvent( - report)); - else { // RawXY - auto divertedXY = _reprog_controls->divertedRawXYEvent(report); - for(const auto& button : this->_buttons) - if(button.second->pressed()) - button.second->move(divertedXY.x, divertedXY.y); + if(!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler({ + [index=_reprog_controls->featureIndex()](const hidpp::Report& report)->bool { + if(report.feature() == index) { + switch(report.function()) { + case hidpp20::ReprogControls::DivertedButtonEvent: + return true; + case hidpp20::ReprogControls::DivertedRawXYEvent: return true; + default: return false; + } + } + return false; + }, + [this](const hidpp::Report& report)->void { + switch(report.function()) { + case hidpp20::ReprogControls::DivertedButtonEvent: + this->_buttonEvent(_reprog_controls->divertedButtonEvent(report)); + break; + case hidpp20::ReprogControls::DivertedRawXYEvent: { + auto divertedXY = _reprog_controls->divertedRawXYEvent(report); + for(const auto& button : this->_buttons) + if(button.second->pressed()) + button.second->move(divertedXY.x, divertedXY.y); + break; + } + default: break; + } } - }; - - _device->hidpp20().addEventHandler(EVENTHANDLER_NAME, handler); + }); } } diff --git a/src/logid/features/RemapButton.h b/src/logid/features/RemapButton.h index 5dd8821..fd0de19 100644 --- a/src/logid/features/RemapButton.h +++ b/src/logid/features/RemapButton.h @@ -108,6 +108,7 @@ namespace features }; std::shared_ptr _ipc_interface; + std::optional _ev_handler; }; }} diff --git a/src/logid/features/ThumbWheel.cpp b/src/logid/features/ThumbWheel.cpp index a3b80da..efe67ec 100644 --- a/src/logid/features/ThumbWheel.cpp +++ b/src/logid/features/ThumbWheel.cpp @@ -27,7 +27,6 @@ using namespace logid; #define FLAG_STR(b) (_wheel_info.capabilities & _thumb_wheel->b ? "YES" : \ "NO") -#define SCROLL_EVENTHANDLER_NAME "THUMB_WHEEL" std::shared_ptr _genAction( Device* dev, std::optional& conf, @@ -118,7 +117,8 @@ ThumbWheel::ThumbWheel(Device *dev) : DeviceFeature(dev), _wheel_info(), ThumbWheel::~ThumbWheel() { - _device->hidpp20().removeEventHandler(SCROLL_EVENTHANDLER_NAME); + if(_ev_handler.has_value()) + _device->hidpp20().removeEventHandler(_ev_handler.value()); } void ThumbWheel::configure() @@ -132,20 +132,17 @@ void ThumbWheel::configure() void ThumbWheel::listen() { - if(_device->hidpp20().eventHandlers().find(SCROLL_EVENTHANDLER_NAME) == - _device->hidpp20().eventHandlers().end()) { - auto handler = std::make_shared(); - handler->condition = [index=_thumb_wheel->featureIndex()] - (hidpp::Report& report)->bool { - return (report.feature() == index) && (report.function() == - hidpp20::ThumbWheel::Event); - }; - - handler->callback = [this](hidpp::Report& report)->void { - this->_handleEvent(_thumb_wheel->thumbwheelEvent(report)); - }; - - _device->hidpp20().addEventHandler(SCROLL_EVENTHANDLER_NAME, handler); + if(!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler({ + [index=_thumb_wheel->featureIndex()] + (const hidpp::Report& report)->bool { + return (report.feature() == index) && + (report.function() == hidpp20::ThumbWheel::Event); + }, + [this](const hidpp::Report& report)->void { + _handleEvent(_thumb_wheel->thumbwheelEvent(report)); + } + }); } } diff --git a/src/logid/features/ThumbWheel.h b/src/logid/features/ThumbWheel.h index 099653b..e894d5d 100644 --- a/src/logid/features/ThumbWheel.h +++ b/src/logid/features/ThumbWheel.h @@ -56,6 +56,8 @@ namespace features bool _last_proxy = false; bool _last_touch = false; std::optional& _config; + + std::optional _ev_handler; }; }}