internal/input: refactoring: clean up touch implementations

This commit is contained in:
Hajime Hoshi 2024-10-26 19:46:46 +09:00
parent 01dc4ed9b1
commit 6fd9044bcf

View File

@ -23,16 +23,17 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/hook" "github.com/hajimehoshi/ebiten/v2/internal/hook"
) )
type pos struct {
x int
y int
}
type gamepadState struct { type gamepadState struct {
buttonDurations [ebiten.GamepadButtonMax + 1]int buttonDurations [ebiten.GamepadButtonMax + 1]int
standardButtonDurations [ebiten.StandardGamepadButtonMax + 1]int standardButtonDurations [ebiten.StandardGamepadButtonMax + 1]int
} }
type touchState struct {
duration int
x int
y int
}
type inputState struct { type inputState struct {
keyDurations [ebiten.KeyMax + 1]int keyDurations [ebiten.KeyMax + 1]int
prevKeyDurations [ebiten.KeyMax + 1]int prevKeyDurations [ebiten.KeyMax + 1]int
@ -43,11 +44,8 @@ type inputState struct {
gamepadStates map[ebiten.GamepadID]gamepadState gamepadStates map[ebiten.GamepadID]gamepadState
prevGamepadStates map[ebiten.GamepadID]gamepadState prevGamepadStates map[ebiten.GamepadID]gamepadState
touchIDs map[ebiten.TouchID]struct{} touchStates map[ebiten.TouchID]touchState
touchDurations map[ebiten.TouchID]int prevTouchStates map[ebiten.TouchID]touchState
touchPositions map[ebiten.TouchID]pos
prevTouchDurations map[ebiten.TouchID]int
prevTouchPositions map[ebiten.TouchID]pos
gamepadIDsBuf []ebiten.GamepadID gamepadIDsBuf []ebiten.GamepadID
touchIDsBuf []ebiten.TouchID touchIDsBuf []ebiten.TouchID
@ -58,12 +56,8 @@ type inputState struct {
var theInputState = &inputState{ var theInputState = &inputState{
gamepadStates: map[ebiten.GamepadID]gamepadState{}, gamepadStates: map[ebiten.GamepadID]gamepadState{},
prevGamepadStates: map[ebiten.GamepadID]gamepadState{}, prevGamepadStates: map[ebiten.GamepadID]gamepadState{},
touchStates: map[ebiten.TouchID]touchState{},
touchIDs: map[ebiten.TouchID]struct{}{}, prevTouchStates: map[ebiten.TouchID]touchState{},
touchDurations: map[ebiten.TouchID]int{},
touchPositions: map[ebiten.TouchID]pos{},
prevTouchDurations: map[ebiten.TouchID]int{},
prevTouchPositions: map[ebiten.TouchID]pos{},
} }
func init() { func init() {
@ -130,14 +124,7 @@ func (i *inputState) update() {
// Remove disconnected gamepads. // Remove disconnected gamepads.
for id := range i.gamepadStates { for id := range i.gamepadStates {
var found bool if !slices.Contains(i.gamepadIDsBuf, id) {
for _, id2 := range i.gamepadIDsBuf {
if id == id2 {
found = true
break
}
}
if !found {
delete(i.gamepadStates, id) delete(i.gamepadStates, id)
} }
} }
@ -145,27 +132,23 @@ func (i *inputState) update() {
// Touches // Touches
// Copy the touch durations and positions. // Copy the touch durations and positions.
clear(i.prevTouchPositions) clear(i.prevTouchStates)
for id := range i.touchDurations { for id, state := range i.touchStates {
i.prevTouchDurations[id] = i.touchDurations[id] i.prevTouchStates[id] = state
}
clear(i.prevTouchPositions)
for id := range i.touchPositions {
i.prevTouchPositions[id] = i.touchPositions[id]
} }
clear(i.touchIDs)
i.touchIDsBuf = ebiten.AppendTouchIDs(i.touchIDsBuf[:0]) i.touchIDsBuf = ebiten.AppendTouchIDs(i.touchIDsBuf[:0])
for _, id := range i.touchIDsBuf { for _, id := range i.touchIDsBuf {
i.touchIDs[id] = struct{}{} state := i.touchStates[id]
i.touchDurations[id]++ state.duration++
x, y := ebiten.TouchPosition(id) state.x, state.y = ebiten.TouchPosition(id)
i.touchPositions[id] = pos{x: x, y: y} i.touchStates[id] = state
} }
for id := range i.touchDurations {
if _, ok := i.touchIDs[id]; !ok { // Remove released touches.
delete(i.touchDurations, id) for id := range i.touchStates {
delete(i.touchPositions, id) if !slices.Contains(i.touchIDsBuf, id) {
delete(i.touchStates, id)
} }
} }
} }
@ -625,10 +608,11 @@ func AppendJustPressedTouchIDs(touchIDs []ebiten.TouchID) []ebiten.TouchID {
defer theInputState.m.RUnlock() defer theInputState.m.RUnlock()
origLen := len(touchIDs) origLen := len(touchIDs)
for id, s := range theInputState.touchDurations { for id, state := range theInputState.touchStates {
if s == 1 { if state.duration != 1 {
touchIDs = append(touchIDs, id) continue
} }
touchIDs = append(touchIDs, id)
} }
slices.Sort(touchIDs[origLen:]) slices.Sort(touchIDs[origLen:])
@ -656,10 +640,14 @@ func AppendJustReleasedTouchIDs(touchIDs []ebiten.TouchID) []ebiten.TouchID {
defer theInputState.m.RUnlock() defer theInputState.m.RUnlock()
origLen := len(touchIDs) origLen := len(touchIDs)
for id := range theInputState.prevTouchDurations { for id, state := range theInputState.prevTouchStates {
if theInputState.touchDurations[id] == 0 && theInputState.prevTouchDurations[id] > 0 { if state.duration == 0 {
touchIDs = append(touchIDs, id) continue
} }
if theInputState.touchStates[id].duration != 0 {
continue
}
touchIDs = append(touchIDs, id)
} }
slices.Sort(touchIDs[origLen:]) slices.Sort(touchIDs[origLen:])
@ -676,7 +664,9 @@ func IsTouchJustReleased(id ebiten.TouchID) bool {
theInputState.m.RLock() theInputState.m.RLock()
defer theInputState.m.RUnlock() defer theInputState.m.RUnlock()
return theInputState.touchDurations[id] == 0 && theInputState.prevTouchDurations[id] > 0 current := theInputState.touchStates[id]
prev := theInputState.prevTouchStates[id]
return current.duration == 0 && prev.duration > 0
} }
// TouchPressDuration returns how long the touch remains in ticks (Update). // TouchPressDuration returns how long the touch remains in ticks (Update).
@ -687,7 +677,7 @@ func IsTouchJustReleased(id ebiten.TouchID) bool {
func TouchPressDuration(id ebiten.TouchID) int { func TouchPressDuration(id ebiten.TouchID) int {
theInputState.m.RLock() theInputState.m.RLock()
defer theInputState.m.RUnlock() defer theInputState.m.RUnlock()
return theInputState.touchDurations[id] return theInputState.touchStates[id].duration
} }
// TouchPositionInPreviousTick returns the position in the previous tick. // TouchPositionInPreviousTick returns the position in the previous tick.
@ -700,6 +690,6 @@ func TouchPositionInPreviousTick(id ebiten.TouchID) (int, int) {
theInputState.m.RLock() theInputState.m.RLock()
defer theInputState.m.RUnlock() defer theInputState.m.RUnlock()
p := theInputState.prevTouchPositions[id] state := theInputState.prevTouchStates[id]
return p.x, p.y return state.x, state.y
} }