Clamp values falling outside of the axis bounds.

This commit is contained in:
Anna Rose Wiggins 2025-07-10 19:58:31 -04:00
parent 681e1fef70
commit a6ad1b609a
3 changed files with 17 additions and 6 deletions

View file

@ -4,17 +4,22 @@ import (
"golang.org/x/exp/constraints"
)
func AbsInt[T constraints.Integer](value T) T {
type Numeric interface {
constraints.Integer | constraints.Float
}
func Abs[T Numeric](value T) T {
return max(value, -value)
}
// LerpInt linearly interpolates between two integer values using
// a float64 index value
func LerpInt[T constraints.Integer](min, max T, t float64) T {
t = Clamp(t, 0.0, 1.0)
return T((1-t)*float64(min) + t*float64(max))
}
func ClampInt[T constraints.Integer](value, min, max T) T {
func Clamp[T Numeric](value, min, max T) T {
if value < min {
value = min
}

View file

@ -51,7 +51,7 @@ func NewRuleTargetAxis(device_name string,
return nil, errors.New("deadzone_end must be a higher value than deadzone_start")
}
deadzoneSize := AbsInt(deadzoneEnd - deadzoneStart)
deadzoneSize := Abs(deadzoneEnd - deadzoneStart)
// Our output range is limited to 16 bits, but we represent values internally with 32 bits.
// As a result, we shouldn't need to worry about integer overruns
@ -82,6 +82,7 @@ func NewRuleTargetAxis(device_name string,
// in the deadzone, among other things.
func (target *RuleTargetAxis) NormalizeValue(value int32) int32 {
axisStrength := float64(value-target.deadzoneSize) / float64(target.axisSize)
if target.Inverted {
axisStrength = 1.0 - axisStrength
}
@ -90,7 +91,7 @@ func (target *RuleTargetAxis) NormalizeValue(value int32) int32 {
}
func (target *RuleTargetAxis) CreateEvent(value int32, mode *string) *evdev.InputEvent {
value = ClampInt(value, AxisValueMin, AxisValueMax)
value = Clamp(value, AxisValueMin, AxisValueMax)
return &evdev.InputEvent{
Type: evdev.EV_ABS,
Code: target.Axis,

View file

@ -69,8 +69,8 @@ func (t *RuleTargetAxisTests) TestNewRuleTargetAxis() {
// If Absinfo has an error, we should create a device with permissive bounds
t.call.Unset()
t.mock.On("AbsInfos").Return(nil, errors.New("Test Error"))
ruleTarget, err = NewRuleTargetAxis("", t.mock, evdev.ABS_Y, false, -500, 500)
t.mock.On("AbsInfos").Return(map[evdev.EvCode]evdev.AbsInfo{}, errors.New("Test Error"))
ruleTarget, err = NewRuleTargetAxis("", t.mock, evdev.ABS_X, false, 0, 0)
t.Nil(err)
t.Equal(AxisValueMax-AxisValueMin, ruleTarget.axisSize)
}
@ -92,6 +92,11 @@ func (t *RuleTargetAxisTests) TestNormalizeValue() {
ruleTarget, _ = NewRuleTargetAxis("", t.mock, evdev.ABS_X, true, 0, 0)
t.Equal(AxisValueMax, ruleTarget.NormalizeValue(int32(0)))
t.Equal(AxisValueMin, ruleTarget.NormalizeValue(int32(10000)))
// Normalization past the stated axis bounds should clamp
ruleTarget, _ = NewRuleTargetAxis("", t.mock, evdev.ABS_X, false, 0, 0)
t.Equal(AxisValueMin, ruleTarget.NormalizeValue(int32(-30000)))
t.Equal(AxisValueMax, ruleTarget.NormalizeValue(int32(30000)))
}
func (t *RuleTargetAxisTests) TestMatchEvent() {