From 982a68e5a21f3b2dff494132b34639084fd3e9ac Mon Sep 17 00:00:00 2001 From: seebs Date: Sun, 24 May 2020 13:20:21 -0500 Subject: [PATCH] inpututil: use slices for maps where keys are small contiguous integers (#1169) Durations for key presses and gamepad button presses were being stored in map[int]int, where the key values were always small integers, and furthermore, were always contiguous and contained the whole set. It's much faster and cheaper to do those with slices. We could probably do this with mouse buttons, but I was wary of that code because I don't see any handling for more-than-three-button mice. Similar logic could perhaps apply to touch events, but there it might make more sense to use a dynamic allocation of some kind. It might be more efficient to just swap the two slices back and forth, computing the new values from the previous values and then swapping the slice arrays themselves, but that seemed like a more intrusive change. --- inpututil/inpututil.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/inpututil/inpututil.go b/inpututil/inpututil.go index df8a6a063..83df34b61 100644 --- a/inpututil/inpututil.go +++ b/inpututil/inpututil.go @@ -24,8 +24,8 @@ import ( ) type inputState struct { - keyDurations map[ebiten.Key]int - prevKeyDurations map[ebiten.Key]int + keyDurations []int + prevKeyDurations []int mouseButtonDurations map[ebiten.MouseButton]int prevMouseButtonDurations map[ebiten.MouseButton]int @@ -33,8 +33,8 @@ type inputState struct { gamepadIDs map[int]struct{} prevGamepadIDs map[int]struct{} - gamepadButtonDurations map[int]map[ebiten.GamepadButton]int - prevGamepadButtonDurations map[int]map[ebiten.GamepadButton]int + gamepadButtonDurations map[int][]int + prevGamepadButtonDurations map[int][]int touchDurations map[int]int prevTouchDurations map[int]int @@ -43,8 +43,8 @@ type inputState struct { } var theInputState = &inputState{ - keyDurations: map[ebiten.Key]int{}, - prevKeyDurations: map[ebiten.Key]int{}, + keyDurations: make([]int, ebiten.KeyMax+1), + prevKeyDurations: make([]int, ebiten.KeyMax+1), mouseButtonDurations: map[ebiten.MouseButton]int{}, prevMouseButtonDurations: map[ebiten.MouseButton]int{}, @@ -52,8 +52,8 @@ var theInputState = &inputState{ gamepadIDs: map[int]struct{}{}, prevGamepadIDs: map[int]struct{}{}, - gamepadButtonDurations: map[int]map[ebiten.GamepadButton]int{}, - prevGamepadButtonDurations: map[int]map[ebiten.GamepadButton]int{}, + gamepadButtonDurations: map[int][]int{}, + prevGamepadButtonDurations: map[int][]int{}, touchDurations: map[int]int{}, prevTouchDurations: map[int]int{}, @@ -71,8 +71,8 @@ func (i *inputState) update() { defer i.m.Unlock() // Keyboard + copy(i.prevKeyDurations[:], i.keyDurations[:]) for k := ebiten.Key(0); k <= ebiten.KeyMax; k++ { - i.prevKeyDurations[k] = i.keyDurations[k] if ebiten.IsKeyPressed(k) { i.keyDurations[k]++ } else { @@ -103,19 +103,16 @@ func (i *inputState) update() { } // Copy the gamepad button durations. - i.prevGamepadButtonDurations = map[int]map[ebiten.GamepadButton]int{} + i.prevGamepadButtonDurations = map[int][]int{} for id, ds := range i.gamepadButtonDurations { - i.prevGamepadButtonDurations[id] = map[ebiten.GamepadButton]int{} - for b, d := range ds { - i.prevGamepadButtonDurations[id][b] = d - } + i.prevGamepadButtonDurations[id] = append([]int{}, ds...) } i.gamepadIDs = map[int]struct{}{} for _, id := range ebiten.GamepadIDs() { i.gamepadIDs[id] = struct{}{} if _, ok := i.gamepadButtonDurations[id]; !ok { - i.gamepadButtonDurations[id] = map[ebiten.GamepadButton]int{} + i.gamepadButtonDurations[id] = make([]int, ebiten.GamepadButtonMax+1) } n := ebiten.GamepadButtonNum(id) for b := ebiten.GamepadButton(0); b < ebiten.GamepadButton(n); b++ {