Use event handler ids for hidpp::Device

This commit is contained in:
pixl 2022-03-05 21:32:12 -05:00
parent a23f0ea725
commit f76d9dfaf5
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
14 changed files with 107 additions and 104 deletions

View File

@ -31,8 +31,8 @@ namespace dj
{ {
struct EventHandler struct EventHandler
{ {
std::function<bool(Report&)> condition; std::function<bool(const Report&)> condition;
std::function<void(Report&)> callback; std::function<void(const Report&)> callback;
}; };
class InvalidReceiver : public std::exception class InvalidReceiver : public std::exception

View File

@ -213,23 +213,17 @@ Device::~Device()
_raw_device->removeEventHandler(_raw_handler); _raw_device->removeEventHandler(_raw_handler);
} }
void Device::addEventHandler(const std::string& nickname, Device::EvHandlerId Device::addEventHandler(EventHandler handler)
const std::shared_ptr<EventHandler>& handler)
{ {
assert(_event_handlers.find(nickname) == _event_handlers.end()); std::lock_guard<std::mutex> lock(_event_handler_lock);
_event_handlers.emplace_front(std::move(handler));
_event_handlers.emplace(nickname, handler); return _event_handlers.cbegin();
} }
void Device::removeEventHandler(const std::string& nickname) void Device::removeEventHandler(EvHandlerId id)
{ {
_event_handlers.erase(nickname); std::lock_guard<std::mutex> lock(_event_handler_lock);
} _event_handlers.erase(id);
const std::map<std::string, std::shared_ptr<EventHandler>>&
Device::eventHandlers()
{
return _event_handlers;
} }
void Device::handleEvent(Report& report) void Device::handleEvent(Report& report)
@ -237,9 +231,10 @@ void Device::handleEvent(Report& report)
if(responseReport(report)) if(responseReport(report))
return; return;
std::lock_guard<std::mutex> lock(_event_handler_lock);
for(auto& handler : _event_handlers) for(auto& handler : _event_handlers)
if(handler.second->condition(report)) if(handler.condition(report))
handler.second->callback(report); handler.callback(report);
} }
Report Device::sendReport(const Report &report) Report Device::sendReport(const Report &report)

View File

@ -46,6 +46,8 @@ namespace hidpp
class Device class Device
{ {
public: public:
typedef std::list<EventHandler>::const_iterator EvHandlerId;
class InvalidDevice : std::exception class InvalidDevice : std::exception
{ {
public: public:
@ -80,11 +82,8 @@ namespace hidpp
std::string name() const; std::string name() const;
uint16_t pid() const; uint16_t pid() const;
void addEventHandler(const std::string& nickname, EvHandlerId addEventHandler(EventHandler handler);
const std::shared_ptr<EventHandler>& handler); void removeEventHandler(EvHandlerId id);
void removeEventHandler(const std::string& nickname);
const std::map<std::string, std::shared_ptr<EventHandler>>&
eventHandlers();
virtual Report sendReport(const Report& report); virtual Report sendReport(const Report& report);
void sendReportNoResponse(Report report); void sendReportNoResponse(Report report);
@ -117,7 +116,8 @@ namespace hidpp
std::mutex _slot_lock; std::mutex _slot_lock;
std::optional<Report> _report_slot; std::optional<Report> _report_slot;
std::map<std::string, std::shared_ptr<EventHandler>> _event_handlers; std::mutex _event_handler_lock;
std::list<EventHandler> _event_handlers;
}; };
} } } } } }

View File

@ -69,7 +69,8 @@ ThumbWheel::ThumbwheelStatus ThumbWheel::setStatus(bool divert, bool invert)
return status; return status;
} }
ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(hidpp::Report& report) ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(
const hidpp::Report& report)
{ {
assert(report.function() == Event); assert(report.function() == Event);
ThumbwheelEvent event{}; ThumbwheelEvent event{};

View File

@ -86,7 +86,8 @@ namespace hidpp20
ThumbwheelStatus setStatus(bool divert, bool invert); ThumbwheelStatus setStatus(bool divert, bool invert);
ThumbwheelEvent thumbwheelEvent(hidpp::Report& report); [[nodiscard]] ThumbwheelEvent thumbwheelEvent(
const hidpp::Report& report);
}; };
}}} }}}

View File

@ -174,14 +174,14 @@ void RawDevice::sendReport(const std::vector<uint8_t>& report)
RawDevice::EvHandlerId RawDevice::addEventHandler(RawEventHandler handler) RawDevice::EvHandlerId RawDevice::addEventHandler(RawEventHandler handler)
{ {
std::unique_lock<std::mutex> lock(_event_handler_lock); std::lock_guard<std::mutex> lock(_event_handler_lock);
_event_handlers.emplace_front(std::move(handler)); _event_handlers.emplace_front(std::move(handler));
return _event_handlers.cbegin(); return _event_handlers.cbegin();
} }
void RawDevice::removeEventHandler(RawDevice::EvHandlerId id) void RawDevice::removeEventHandler(RawDevice::EvHandlerId id)
{ {
std::unique_lock<std::mutex> lock(_event_handler_lock); std::lock_guard<std::mutex> lock(_event_handler_lock);
_event_handlers.erase(id); _event_handlers.erase(id);
} }

View File

@ -18,8 +18,6 @@
#include "DeviceStatus.h" #include "DeviceStatus.h"
#include "../util/task.h" #include "../util/task.h"
#define EVENTHANDLER_NAME "devicestatus"
using namespace logid::features; using namespace logid::features;
using namespace logid::backend; 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() void DeviceStatus::configure()
{ {
// Do nothing // Do nothing
@ -48,23 +52,19 @@ void DeviceStatus::configure()
void DeviceStatus::listen() void DeviceStatus::listen()
{ {
if(_device->hidpp20().eventHandlers().find(EVENTHANDLER_NAME) == if(!_ev_handler.has_value()) {
_device->hidpp20().eventHandlers().end()) { _ev_handler = _device->hidpp20().addEventHandler({
auto handler = std::make_shared<hidpp::EventHandler>(); [index=_wireless_device_status->featureIndex()](
handler->condition = [index=_wireless_device_status->featureIndex()](
const hidpp::Report& report)->bool { const hidpp::Report& report)->bool {
return report.feature() == index && report.function() == return report.feature() == index && report.function() ==
hidpp20::WirelessDeviceStatus::StatusBroadcast; hidpp20::WirelessDeviceStatus::StatusBroadcast;
}; },
[dev=this->_device](const hidpp::Report& report) {
handler->callback = [dev=this->_device]( auto event =
const hidpp::Report& report)->void { hidpp20::WirelessDeviceStatus::statusBroadcastEvent(report);
auto event = hidpp20::WirelessDeviceStatus::statusBroadcastEvent(
report);
if(event.reconfNeeded) if(event.reconfNeeded)
spawn_task( [dev](){ dev->wakeup(); }); spawn_task( [dev](){ dev->wakeup(); });
}; }
});
_device->hidpp20().addEventHandler(EVENTHANDLER_NAME, handler);
} }
} }

View File

@ -30,9 +30,11 @@ namespace features
{ {
public: public:
explicit DeviceStatus(Device* dev); explicit DeviceStatus(Device* dev);
~DeviceStatus();
virtual void configure(); virtual void configure();
virtual void listen(); virtual void listen();
private: private:
std::optional<backend::hidpp::Device::EvHandlerId> _ev_handler;
std::shared_ptr<backend::hidpp20::WirelessDeviceStatus> std::shared_ptr<backend::hidpp20::WirelessDeviceStatus>
_wireless_device_status; _wireless_device_status;
}; };

View File

@ -70,7 +70,8 @@ HiresScroll::HiresScroll(Device *dev) : DeviceFeature(dev),
HiresScroll::~HiresScroll() HiresScroll::~HiresScroll()
{ {
_device->hidpp20().removeEventHandler(MOVE_EVENTHANDLER_NAME); if(_ev_handler.has_value())
_device->hidpp20().removeEventHandler(_ev_handler.value());
} }
void HiresScroll::configure() void HiresScroll::configure()
@ -83,20 +84,17 @@ void HiresScroll::configure()
void HiresScroll::listen() void HiresScroll::listen()
{ {
if(_device->hidpp20().eventHandlers().find(MOVE_EVENTHANDLER_NAME) == if(!_ev_handler.has_value()) {
_device->hidpp20().eventHandlers().end()) { _ev_handler = _device->hidpp20().addEventHandler({
auto handler = std::make_shared<hidpp::EventHandler>(); [index=_hires_scroll->featureIndex()](
handler->condition = [index=_hires_scroll->featureIndex()] const hidpp::Report& report)->bool {
(hidpp::Report& report)->bool {
return (report.feature() == index) && (report.function() == return (report.feature() == index) && (report.function() ==
hidpp20::HiresScroll::WheelMovement); hidpp20::HiresScroll::WheelMovement);
}; },
[this](const hidpp::Report& report) {
handler->callback = [this](hidpp::Report& report)->void { _handleScroll(_hires_scroll->wheelMovementEvent(report));
this->_handleScroll(_hires_scroll->wheelMovementEvent(report)); }
}; });
_device->hidpp20().addEventHandler(MOVE_EVENTHANDLER_NAME, handler);
} }
} }

View File

@ -36,6 +36,8 @@ namespace features
uint8_t getMode(); uint8_t getMode();
void setMode(uint8_t mode); void setMode(uint8_t mode);
private: private:
std::optional<backend::hidpp::Device::EvHandlerId> _ev_handler;
void _makeAction(std::shared_ptr<actions::Gesture>& gesture, void _makeAction(std::shared_ptr<actions::Gesture>& gesture,
std::optional<config::Gesture>& config, std::optional<config::Gesture>& config,
const std::string& direction); const std::string& direction);

View File

@ -28,8 +28,6 @@ using namespace logid::actions;
#define HIDPP20_REPROG_REBIND (hidpp20::ReprogControls::ChangeTemporaryDivert \ #define HIDPP20_REPROG_REBIND (hidpp20::ReprogControls::ChangeTemporaryDivert \
| hidpp20::ReprogControls::ChangeRawXYDivert) | hidpp20::ReprogControls::ChangeRawXYDivert)
#define EVENTHANDLER_NAME "REMAP_BUTTON"
RemapButton::RemapButton(Device *dev): DeviceFeature(dev), RemapButton::RemapButton(Device *dev): DeviceFeature(dev),
_config (dev->activeProfile().buttons), _config (dev->activeProfile().buttons),
_ipc_node (dev->ipcNode()->make_child("buttons")) _ipc_node (dev->ipcNode()->make_child("buttons"))
@ -99,7 +97,8 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev),
RemapButton::~RemapButton() RemapButton::~RemapButton()
{ {
_device->hidpp20().removeEventHandler(EVENTHANDLER_NAME); if(_ev_handler.has_value())
_device->hidpp20().removeEventHandler(_ev_handler.value());
} }
void RemapButton::configure() void RemapButton::configure()
@ -110,30 +109,35 @@ void RemapButton::configure()
void RemapButton::listen() void RemapButton::listen()
{ {
if(_device->hidpp20().eventHandlers().find(EVENTHANDLER_NAME) == if(!_ev_handler.has_value()) {
_device->hidpp20().eventHandlers().end()) { _ev_handler = _device->hidpp20().addEventHandler({
auto handler = std::make_shared<hidpp::EventHandler>(); [index=_reprog_controls->featureIndex()](const hidpp::Report& report)->bool {
handler->condition = [index=_reprog_controls->featureIndex()] if(report.feature() == index) {
(hidpp::Report& report)->bool { switch(report.function()) {
return (report.feature() == index) && ((report.function() == case hidpp20::ReprogControls::DivertedButtonEvent:
hidpp20::ReprogControls::DivertedButtonEvent) || (report return true;
.function() == hidpp20::ReprogControls::DivertedRawXYEvent)); case hidpp20::ReprogControls::DivertedRawXYEvent: return true;
}; default: return false;
}
handler->callback = [this](hidpp::Report& report)->void { }
if(report.function() == return false;
hidpp20::ReprogControls::DivertedButtonEvent) },
this->_buttonEvent(_reprog_controls->divertedButtonEvent( [this](const hidpp::Report& report)->void {
report)); switch(report.function()) {
else { // RawXY case hidpp20::ReprogControls::DivertedButtonEvent:
this->_buttonEvent(_reprog_controls->divertedButtonEvent(report));
break;
case hidpp20::ReprogControls::DivertedRawXYEvent: {
auto divertedXY = _reprog_controls->divertedRawXYEvent(report); auto divertedXY = _reprog_controls->divertedRawXYEvent(report);
for(const auto& button : this->_buttons) for(const auto& button : this->_buttons)
if(button.second->pressed()) if(button.second->pressed())
button.second->move(divertedXY.x, divertedXY.y); button.second->move(divertedXY.x, divertedXY.y);
break;
} }
}; default: break;
}
_device->hidpp20().addEventHandler(EVENTHANDLER_NAME, handler); }
});
} }
} }

View File

@ -108,6 +108,7 @@ namespace features
}; };
std::shared_ptr<IPC> _ipc_interface; std::shared_ptr<IPC> _ipc_interface;
std::optional<backend::hidpp::Device::EvHandlerId> _ev_handler;
}; };
}} }}

View File

@ -27,7 +27,6 @@ using namespace logid;
#define FLAG_STR(b) (_wheel_info.capabilities & _thumb_wheel->b ? "YES" : \ #define FLAG_STR(b) (_wheel_info.capabilities & _thumb_wheel->b ? "YES" : \
"NO") "NO")
#define SCROLL_EVENTHANDLER_NAME "THUMB_WHEEL"
std::shared_ptr<actions::Action> _genAction( std::shared_ptr<actions::Action> _genAction(
Device* dev, std::optional<config::BasicAction>& conf, Device* dev, std::optional<config::BasicAction>& conf,
@ -118,7 +117,8 @@ ThumbWheel::ThumbWheel(Device *dev) : DeviceFeature(dev), _wheel_info(),
ThumbWheel::~ThumbWheel() ThumbWheel::~ThumbWheel()
{ {
_device->hidpp20().removeEventHandler(SCROLL_EVENTHANDLER_NAME); if(_ev_handler.has_value())
_device->hidpp20().removeEventHandler(_ev_handler.value());
} }
void ThumbWheel::configure() void ThumbWheel::configure()
@ -132,20 +132,17 @@ void ThumbWheel::configure()
void ThumbWheel::listen() void ThumbWheel::listen()
{ {
if(_device->hidpp20().eventHandlers().find(SCROLL_EVENTHANDLER_NAME) == if(!_ev_handler.has_value()) {
_device->hidpp20().eventHandlers().end()) { _ev_handler = _device->hidpp20().addEventHandler({
auto handler = std::make_shared<hidpp::EventHandler>(); [index=_thumb_wheel->featureIndex()]
handler->condition = [index=_thumb_wheel->featureIndex()] (const hidpp::Report& report)->bool {
(hidpp::Report& report)->bool { return (report.feature() == index) &&
return (report.feature() == index) && (report.function() == (report.function() == hidpp20::ThumbWheel::Event);
hidpp20::ThumbWheel::Event); },
}; [this](const hidpp::Report& report)->void {
_handleEvent(_thumb_wheel->thumbwheelEvent(report));
handler->callback = [this](hidpp::Report& report)->void { }
this->_handleEvent(_thumb_wheel->thumbwheelEvent(report)); });
};
_device->hidpp20().addEventHandler(SCROLL_EVENTHANDLER_NAME, handler);
} }
} }

View File

@ -56,6 +56,8 @@ namespace features
bool _last_proxy = false; bool _last_proxy = false;
bool _last_touch = false; bool _last_touch = false;
std::optional<config::ThumbWheel>& _config; std::optional<config::ThumbWheel>& _config;
std::optional<backend::hidpp::Device::EvHandlerId> _ev_handler;
}; };
}} }}