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
{
std::function<bool(Report&)> condition;
std::function<void(Report&)> callback;
std::function<bool(const Report&)> condition;
std::function<void(const Report&)> callback;
};
class InvalidReceiver : public std::exception

View File

@ -213,23 +213,17 @@ Device::~Device()
_raw_device->removeEventHandler(_raw_handler);
}
void Device::addEventHandler(const std::string& nickname,
const std::shared_ptr<EventHandler>& handler)
Device::EvHandlerId Device::addEventHandler(EventHandler handler)
{
assert(_event_handlers.find(nickname) == _event_handlers.end());
_event_handlers.emplace(nickname, handler);
std::lock_guard<std::mutex> 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<std::string, std::shared_ptr<EventHandler>>&
Device::eventHandlers()
{
return _event_handlers;
std::lock_guard<std::mutex> 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<std::mutex> 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)

View File

@ -46,6 +46,8 @@ namespace hidpp
class Device
{
public:
typedef std::list<EventHandler>::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<EventHandler>& handler);
void removeEventHandler(const std::string& nickname);
const std::map<std::string, std::shared_ptr<EventHandler>>&
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> _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;
}
ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(hidpp::Report& report)
ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(
const hidpp::Report& report)
{
assert(report.function() == Event);
ThumbwheelEvent event{};

View File

@ -86,7 +86,8 @@ namespace hidpp20
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)
{
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));
return _event_handlers.cbegin();
}
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);
}

View File

@ -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<hidpp::EventHandler>();
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(); });
}
});
}
}

View File

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

View File

@ -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<hidpp::EventHandler>();
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));
}
});
}
}

View File

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

View File

@ -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<hidpp::EventHandler>();
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);
});
}
}

View File

@ -108,6 +108,7 @@ namespace features
};
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" : \
"NO")
#define SCROLL_EVENTHANDLER_NAME "THUMB_WHEEL"
std::shared_ptr<actions::Action> _genAction(
Device* dev, std::optional<config::BasicAction>& 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<hidpp::EventHandler>();
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));
}
});
}
}

View File

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