Start implementing a channel for timer-based events.

This commit is contained in:
Anna Rose Wiggins 2025-07-03 18:11:37 -04:00
parent f12d119116
commit bf1bb868e5
2 changed files with 50 additions and 23 deletions

View file

@ -69,7 +69,15 @@ func main() {
mapEvents(vBuffers, pDevices, rules) mapEvents(vBuffers, pDevices, rules)
} }
type ChannelEventType int
const (
ChannelEventInput ChannelEventType = iota
ChannelEventTimer
)
type ChannelEvent struct { type ChannelEvent struct {
Type ChannelEventType
Device *evdev.InputDevice Device *evdev.InputDevice
Event *evdev.InputEvent Event *evdev.InputEvent
} }
@ -89,31 +97,38 @@ func mapEvents(vBuffers map[string]*virtualdevice.EventBuffer, pDevices map[stri
// Get an event (blocks if necessary) // Get an event (blocks if necessary)
wrapper := <-eventChannel wrapper := <-eventChannel
switch wrapper.Event.Type { switch wrapper.Type {
case evdev.EV_SYN: case ChannelEventInput:
// We've received a SYN_REPORT, so now we send all of our pending events switch wrapper.Event.Type {
for _, buffer := range vBuffers { case evdev.EV_SYN:
buffer.SendEvents() // We've received a SYN_REPORT, so now we send all of our pending events
} for _, buffer := range vBuffers {
buffer.SendEvents()
// TODO: event types are a little weird, because EvCode constants are reused across
// types, but button presses can apparently come across as multiple types.
// This isn't a big problem right now, but when we want to support relative axes
// and/or keyboards, this could get hairy.
case evdev.EV_KEY:
case evdev.EV_ABS:
case evdev.EV_MSC:
// We have a matchable event type. Check all the events
for _, rule := range rules {
outputEvent := rule.MatchEvent(wrapper.Device, wrapper.Event, &mode)
if outputEvent == nil {
continue
} }
vBuffers[rule.OutputName()].AddEvent(outputEvent) // TODO: event types are a little weird, because EvCode constants are reused across
// types, but button presses can apparently come across as multiple types.
// This isn't a big problem right now, but when we want to support relative axes
// and/or keyboards, this could get hairy.
case evdev.EV_KEY:
case evdev.EV_ABS:
case evdev.EV_MSC:
// We have a matchable event type. Check all the events
for _, rule := range rules {
outputEvent := rule.MatchEvent(wrapper.Device, wrapper.Event, &mode)
if outputEvent == nil {
continue
}
vBuffers[rule.OutputName()].AddEvent(outputEvent)
}
default:
logger.Logf("DEBUG: Unprocessed event: %d %d %d", wrapper.Event.Type, wrapper.Event.Code, wrapper.Event.Value)
} }
default: case ChannelEventTimer:
logger.Logf("DEBUG: Unprocessed event: %d %d %d", wrapper.Event.Type, wrapper.Event.Code, wrapper.Event.Value) // Timer events give us the device and event to use directly
// TODO: we need a vbuffer map with device keys
// vBuffers[wrapper.Device].AddEvent(wrapper.Event)
} }
} }
} }

View file

@ -1,6 +1,10 @@
package mappingrules package mappingrules
import "github.com/holoplot/go-evdev" import (
"time"
"github.com/holoplot/go-evdev"
)
type MappingRule interface { type MappingRule interface {
MatchEvent(*evdev.InputDevice, *evdev.InputEvent, *string) *evdev.InputEvent MatchEvent(*evdev.InputDevice, *evdev.InputEvent, *string) *evdev.InputEvent
@ -32,6 +36,14 @@ type LatchedMappingRule struct {
State bool State bool
} }
// TODO: How are we going to implement this? It needs to operate on a timer...
type ProportionalAxisMappingRule struct {
MappingRuleBase
Input RuleTarget
Output RuleTarget
LastEvent time.Time
}
type RuleTarget struct { type RuleTarget struct {
DeviceName string DeviceName string
ModeSelect []string ModeSelect []string