From 187a93d80a306dfdca9b1624db8d15b9cdf17abe Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 11 Apr 2017 11:56:05 +0900 Subject: [PATCH] ui: Bug fix: IsKeyPressed might return a wrong value when only one of Shift/Ctrl/Alt keys is pressed --- internal/ui/input.go | 26 --------- internal/ui/input_glfw.go | 60 +++++++++++++++++-- internal/ui/input_js.go | 113 ++++++++++++++++++++++++------------ internal/ui/input_mobile.go | 20 +++++++ 4 files changed, 153 insertions(+), 66 deletions(-) diff --git a/internal/ui/input.go b/internal/ui/input.go index 81e738e34..ab53dc77d 100644 --- a/internal/ui/input.go +++ b/internal/ui/input.go @@ -14,10 +14,6 @@ package ui -import ( - "sync" -) - var currentInput = &input{} type Input interface { @@ -36,38 +32,16 @@ type Touch interface { Position() (x, y int) } -type input struct { - keyPressed [256]bool - mouseButtonPressed [256]bool - cursorX int - cursorY int - gamepads [16]gamePad - touches []touch - m sync.RWMutex -} - func CurrentInput() Input { return currentInput } -func (i *input) IsKeyPressed(key Key) bool { - i.m.RLock() - defer i.m.RUnlock() - return i.keyPressed[key] -} - func (i *input) CursorPosition() (x, y int) { i.m.RLock() defer i.m.RUnlock() return i.cursorX, i.cursorY } -func (i *input) IsMouseButtonPressed(button MouseButton) bool { - i.m.RLock() - defer i.m.RUnlock() - return i.mouseButtonPressed[button] -} - func (i *input) GamepadAxisNum(id int) int { i.m.RLock() defer i.m.RUnlock() diff --git a/internal/ui/input_glfw.go b/internal/ui/input_glfw.go index a50fd613f..fea1a68ca 100644 --- a/internal/ui/input_glfw.go +++ b/internal/ui/input_glfw.go @@ -20,9 +20,55 @@ package ui import ( + "sync" + glfw "github.com/go-gl/glfw/v3.2/glfw" ) +type input struct { + keyPressed map[glfw.Key]bool + mouseButtonPressed map[glfw.MouseButton]bool + cursorX int + cursorY int + gamepads [16]gamePad + touches []touch + m sync.RWMutex +} + +func (i *input) IsKeyPressed(key Key) bool { + i.m.RLock() + defer i.m.RUnlock() + if i.keyPressed == nil { + i.keyPressed = map[glfw.Key]bool{} + } + for gk, k := range glfwKeyCodeToKey { + if k != key { + continue + } + if i.keyPressed[gk] { + return true + } + } + return false +} + +func (i *input) IsMouseButtonPressed(button MouseButton) bool { + i.m.RLock() + defer i.m.RUnlock() + if i.mouseButtonPressed == nil { + i.mouseButtonPressed = map[glfw.MouseButton]bool{} + } + for gb, b := range glfwMouseButtonToMouseButton { + if b != button { + continue + } + if i.mouseButtonPressed[gb] { + return true + } + } + return false +} + var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{ glfw.MouseButtonLeft: MouseButtonLeft, glfw.MouseButtonRight: MouseButtonRight, @@ -33,11 +79,17 @@ func (i *input) update(window *glfw.Window, scale float64) { i.m.Lock() defer i.m.Unlock() - for g, e := range glfwKeyCodeToKey { - i.keyPressed[e] = window.GetKey(g) == glfw.Press + if i.keyPressed == nil { + i.keyPressed = map[glfw.Key]bool{} } - for g, e := range glfwMouseButtonToMouseButton { - i.mouseButtonPressed[e] = window.GetMouseButton(g) == glfw.Press + for gk := range glfwKeyCodeToKey { + i.keyPressed[gk] = window.GetKey(gk) == glfw.Press + } + if i.mouseButtonPressed == nil { + i.mouseButtonPressed = map[glfw.MouseButton]bool{} + } + for gb := range glfwMouseButtonToMouseButton { + i.mouseButtonPressed[gb] = window.GetMouseButton(gb) == glfw.Press } x, y := window.GetCursorPos() i.cursorX = int(x / scale) diff --git a/internal/ui/input_js.go b/internal/ui/input_js.go index 5dcd21da8..73c6eb6fa 100644 --- a/internal/ui/input_js.go +++ b/internal/ui/input_js.go @@ -17,55 +17,96 @@ package ui import ( + "sync" + "github.com/gopherjs/gopherjs/js" ) -func (i *input) keyDown(key int) { - i.m.Lock() - defer i.m.Unlock() - k, ok := keyCodeToKey[key] - if !ok { - return - } - i.keyPressed[k] = true +type input struct { + keyPressed map[int]bool + mouseButtonPressed map[int]bool + cursorX int + cursorY int + gamepads [16]gamePad + touches []touch + m sync.RWMutex } -func (i *input) keyUp(key int) { - i.m.Lock() - defer i.m.Unlock() - k, ok := keyCodeToKey[key] - if !ok { - return +func (i *input) IsKeyPressed(key Key) bool { + i.m.RLock() + defer i.m.RUnlock() + if i.keyPressed == nil { + i.keyPressed = map[int]bool{} } - i.keyPressed[k] = false + for c, k := range keyCodeToKey { + if k != key { + continue + } + if i.keyPressed[c] { + return true + } + } + return false } -func (i *input) mouseDown(button int) { - i.m.Lock() - defer i.m.Unlock() - p := &i.mouseButtonPressed - switch button { - case 0: - p[MouseButtonLeft] = true - case 1: - p[MouseButtonMiddle] = true - case 2: - p[MouseButtonRight] = true - } +var codeToMouseButton = map[int]MouseButton{ + 0: MouseButtonLeft, + 1: MouseButtonMiddle, + 2: MouseButtonRight, } -func (i *input) mouseUp(button int) { +func (i *input) IsMouseButtonPressed(button MouseButton) bool { + i.m.RLock() + defer i.m.RUnlock() + if i.mouseButtonPressed == nil { + i.mouseButtonPressed = map[int]bool{} + } + for c, b := range codeToMouseButton { + if b != button { + continue + } + if i.mouseButtonPressed[c] { + return true + } + } + return false +} + +func (i *input) keyDown(code int) { i.m.Lock() defer i.m.Unlock() - p := &i.mouseButtonPressed - switch button { - case 0: - p[MouseButtonLeft] = false - case 1: - p[MouseButtonMiddle] = false - case 2: - p[MouseButtonRight] = false + if i.keyPressed == nil { + i.keyPressed = map[int]bool{} } + println(code) + i.keyPressed[code] = true +} + +func (i *input) keyUp(code int) { + i.m.Lock() + defer i.m.Unlock() + if i.keyPressed == nil { + i.keyPressed = map[int]bool{} + } + i.keyPressed[code] = false +} + +func (i *input) mouseDown(code int) { + i.m.Lock() + defer i.m.Unlock() + if i.mouseButtonPressed == nil { + i.mouseButtonPressed = map[int]bool{} + } + i.mouseButtonPressed[code] = true +} + +func (i *input) mouseUp(code int) { + i.m.Lock() + defer i.m.Unlock() + if i.mouseButtonPressed == nil { + i.mouseButtonPressed = map[int]bool{} + } + i.mouseButtonPressed[code] = false } func (i *input) setMouseCursor(x, y int) { diff --git a/internal/ui/input_mobile.go b/internal/ui/input_mobile.go index f5a98bfba..63cde58f4 100644 --- a/internal/ui/input_mobile.go +++ b/internal/ui/input_mobile.go @@ -16,6 +16,26 @@ package ui +import ( + "sync" +) + +type input struct { + cursorX int + cursorY int + gamepads [16]gamePad + touches []touch + m sync.RWMutex +} + +func (i *input) IsKeyPressed(key Key) bool { + return false +} + +func (i *input) IsMouseButtonPressed(key MouseButton) bool { + return false +} + func (i *input) updateTouches(touches []Touch) { i.m.Lock() defer i.m.Unlock()