ui: Bug fix: IsKeyPressed might return a wrong value when only one of Shift/Ctrl/Alt keys is pressed

This commit is contained in:
Hajime Hoshi 2017-04-11 11:56:05 +09:00
parent aa1e7e9cd6
commit 187a93d80a
4 changed files with 153 additions and 66 deletions

View File

@ -14,10 +14,6 @@
package ui package ui
import (
"sync"
)
var currentInput = &input{} var currentInput = &input{}
type Input interface { type Input interface {
@ -36,38 +32,16 @@ type Touch interface {
Position() (x, y int) 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 { func CurrentInput() Input {
return currentInput 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) { func (i *input) CursorPosition() (x, y int) {
i.m.RLock() i.m.RLock()
defer i.m.RUnlock() defer i.m.RUnlock()
return i.cursorX, i.cursorY 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 { func (i *input) GamepadAxisNum(id int) int {
i.m.RLock() i.m.RLock()
defer i.m.RUnlock() defer i.m.RUnlock()

View File

@ -20,9 +20,55 @@
package ui package ui
import ( import (
"sync"
glfw "github.com/go-gl/glfw/v3.2/glfw" 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{ var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{
glfw.MouseButtonLeft: MouseButtonLeft, glfw.MouseButtonLeft: MouseButtonLeft,
glfw.MouseButtonRight: MouseButtonRight, glfw.MouseButtonRight: MouseButtonRight,
@ -33,11 +79,17 @@ func (i *input) update(window *glfw.Window, scale float64) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
for g, e := range glfwKeyCodeToKey { if i.keyPressed == nil {
i.keyPressed[e] = window.GetKey(g) == glfw.Press i.keyPressed = map[glfw.Key]bool{}
} }
for g, e := range glfwMouseButtonToMouseButton { for gk := range glfwKeyCodeToKey {
i.mouseButtonPressed[e] = window.GetMouseButton(g) == glfw.Press 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() x, y := window.GetCursorPos()
i.cursorX = int(x / scale) i.cursorX = int(x / scale)

View File

@ -17,55 +17,96 @@
package ui package ui
import ( import (
"sync"
"github.com/gopherjs/gopherjs/js" "github.com/gopherjs/gopherjs/js"
) )
func (i *input) keyDown(key int) { type input struct {
i.m.Lock() keyPressed map[int]bool
defer i.m.Unlock() mouseButtonPressed map[int]bool
k, ok := keyCodeToKey[key] cursorX int
if !ok { cursorY int
return gamepads [16]gamePad
} touches []touch
i.keyPressed[k] = true m sync.RWMutex
} }
func (i *input) keyUp(key int) { func (i *input) IsKeyPressed(key Key) bool {
i.m.Lock() i.m.RLock()
defer i.m.Unlock() defer i.m.RUnlock()
k, ok := keyCodeToKey[key] if i.keyPressed == nil {
if !ok { i.keyPressed = map[int]bool{}
return
} }
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) { var codeToMouseButton = map[int]MouseButton{
i.m.Lock() 0: MouseButtonLeft,
defer i.m.Unlock() 1: MouseButtonMiddle,
p := &i.mouseButtonPressed 2: MouseButtonRight,
switch button {
case 0:
p[MouseButtonLeft] = true
case 1:
p[MouseButtonMiddle] = true
case 2:
p[MouseButtonRight] = true
}
} }
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() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
p := &i.mouseButtonPressed if i.keyPressed == nil {
switch button { i.keyPressed = map[int]bool{}
case 0:
p[MouseButtonLeft] = false
case 1:
p[MouseButtonMiddle] = false
case 2:
p[MouseButtonRight] = false
} }
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) { func (i *input) setMouseCursor(x, y int) {

View File

@ -16,6 +16,26 @@
package ui 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) { func (i *input) updateTouches(touches []Touch) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()