Add latched rules.

This commit is contained in:
Anna Rose Wiggins 2025-07-02 20:05:36 -04:00
parent a078dcb193
commit f5283f33ca
5 changed files with 91 additions and 35 deletions

View file

@ -8,7 +8,6 @@ import (
"strings"
"git.annabunches.net/annabunches/joyful/internal/logger"
"git.annabunches.net/annabunches/joyful/internal/mappingrules"
"github.com/goccy/go-yaml"
"github.com/holoplot/go-evdev"
)
@ -132,29 +131,6 @@ func (parser *ConfigParser) ConnectPhysicalDevices() map[string]*evdev.InputDevi
return deviceMap
}
func (parser *ConfigParser) BuildRules(pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) []mappingrules.MappingRule {
rules := make([]mappingrules.MappingRule, 0)
for _, ruleConfig := range parser.config.Rules {
var newRule mappingrules.MappingRule
var err error
switch strings.ToLower(ruleConfig.Type) {
case RuleTypeSimple:
newRule, err = makeSimpleRule(ruleConfig, pDevs, vDevs)
case RuleTypeCombo:
newRule, err = makeComboRule(ruleConfig, pDevs, vDevs)
}
if err != nil {
logger.LogError(err, "")
continue
}
rules = append(rules, newRule)
}
return rules
}
func makeButtons(numButtons int) []evdev.EvCode {
if numButtons > 56 {
numButtons = 56

View file

@ -2,12 +2,39 @@ package config
import (
"fmt"
"strings"
"git.annabunches.net/annabunches/joyful/internal/logger"
"git.annabunches.net/annabunches/joyful/internal/mappingrules"
"github.com/holoplot/go-evdev"
)
func makeSimpleRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) (mappingrules.MappingRule, error) {
func (parser *ConfigParser) BuildRules(pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) []mappingrules.MappingRule {
rules := make([]mappingrules.MappingRule, 0)
for _, ruleConfig := range parser.config.Rules {
var newRule mappingrules.MappingRule
var err error
switch strings.ToLower(ruleConfig.Type) {
case RuleTypeSimple:
newRule, err = makeSimpleRule(ruleConfig, pDevs, vDevs)
case RuleTypeCombo:
newRule, err = makeComboRule(ruleConfig, pDevs, vDevs)
case RuleTypeLatched:
newRule, err = makeLatchedRule(ruleConfig, pDevs, vDevs)
}
if err != nil {
logger.LogError(err, "")
continue
}
rules = append(rules, newRule)
}
return rules
}
func makeSimpleRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) (*mappingrules.SimpleMappingRule, error) {
input, err := makeRuleTarget(ruleConfig.Input, pDevs)
if err != nil {
return nil, err
@ -19,13 +46,15 @@ func makeSimpleRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice,
}
return &mappingrules.SimpleMappingRule{
MappingRuleBase: mappingrules.MappingRuleBase{
Output: output,
},
Input: input,
Output: output,
Name: ruleConfig.Name,
}, nil
}
func makeComboRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) (mappingrules.MappingRule, error) {
func makeComboRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) (*mappingrules.ComboMappingRule, error) {
inputs := make([]mappingrules.RuleTarget, 0)
for _, inputConfig := range ruleConfig.Inputs {
input, err := makeRuleTarget(inputConfig, pDevs)
@ -41,12 +70,36 @@ func makeComboRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, v
}
return &mappingrules.ComboMappingRule{
MappingRuleBase: mappingrules.MappingRuleBase{
Output: output,
},
Inputs: inputs,
Output: output,
State: 0,
Name: ruleConfig.Name,
}, nil
}
func makeLatchedRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, vDevs map[string]*evdev.InputDevice) (*mappingrules.LatchedMappingRule, error) {
input, err := makeRuleTarget(ruleConfig.Input, pDevs)
if err != nil {
return nil, err
}
output, err := makeRuleTarget(ruleConfig.Output, vDevs)
if err != nil {
return nil, err
}
return &mappingrules.LatchedMappingRule{
MappingRuleBase: mappingrules.MappingRuleBase{
Output: output,
},
Input: input,
Name: ruleConfig.Name,
State: false,
}, nil
}
// makeInputRuleTarget takes an Input declaration from the YAML and returns a fully formed RuleTarget.
func makeRuleTarget(targetConfig RuleTargetConfig, devs map[string]*evdev.InputDevice) (mappingrules.RuleTarget, error) {
ruleTarget := mappingrules.RuleTarget{}

View file

@ -67,4 +67,5 @@ const (
RuleTypeSimple = "simple"
RuleTypeCombo = "combo"
RuleTypeLatched = "latched"
)

View file

@ -5,6 +5,10 @@ import (
"github.com/holoplot/go-evdev"
)
func (rule *MappingRuleBase) OutputName() string {
return rule.Output.DeviceName
}
// eventFromTarget creates an outputtable event from a RuleTarget
func eventFromTarget(output RuleTarget, value int32) *evdev.InputEvent {
return &evdev.InputEvent{
@ -79,10 +83,21 @@ func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev
return nil
}
func (rule *SimpleMappingRule) OutputName() string {
return rule.Output.DeviceName
}
func (rule *LatchedMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent {
if device != rule.Input.Device ||
event.Code != rule.Input.Code ||
valueFromTarget(rule.Input, event) == 0 {
return nil
}
func (rule *ComboMappingRule) OutputName() string {
return rule.Output.DeviceName
// Input is pressed, so toggle state and emit event
var value int32
rule.State = !rule.State
if rule.State {
value = 1
} else {
value = 0
}
return eventFromTarget(rule.Output, value)
}

View file

@ -7,21 +7,32 @@ type MappingRule interface {
OutputName() string
}
type MappingRuleBase struct {
Output RuleTarget
}
// A Simple Mapping Rule can map a button to a button or an axis to an axis.
type SimpleMappingRule struct {
MappingRuleBase
Input RuleTarget
Output RuleTarget
Name string
}
// A Combo Mapping Rule can require multiple physical button presses for a single output button
type ComboMappingRule struct {
MappingRuleBase
Inputs []RuleTarget
Output RuleTarget
Name string
State int
}
type LatchedMappingRule struct {
MappingRuleBase
Input RuleTarget
Name string
State bool
}
type RuleTarget struct {
DeviceName string
Device *evdev.InputDevice