1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-18 02:16:23 -05:00

Working on d2input.go for #487 (#514)

d2input/ is now clear of lint.
This commit is contained in:
Maxime Lavigne (malavv) 2020-07-01 14:03:40 -04:00 committed by GitHub
parent 0272b593fb
commit 973e969002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 248 additions and 81 deletions

View File

@ -2,6 +2,8 @@ package d2common
import "time"
// Now returns how many seconds have elapsed since Unix time (January 1, 1970 UTC)
func Now() float64 {
// Unix time in nanoseconds divided by how many nanoseconds in a second
return float64(time.Now().UnixNano()) / 1000000000.0
}

View File

@ -5,18 +5,15 @@ import (
)
var (
// ErrHasReg shows the input system already has a registered handler
ErrHasReg = errors.New("input system already has provided handler")
// ErrNotReg shows the input system has no registered handler
ErrNotReg = errors.New("input system does not have provided handler")
)
type Priority int
const (
PriorityLow Priority = iota
PriorityDefault
PriorityHigh
)
var singleton inputManager
// HandlerEvent holds the qualifiers for a key or mouse event
type HandlerEvent struct {
KeyMod KeyMod
ButtonMod MouseButtonMod
@ -24,6 +21,7 @@ type HandlerEvent struct {
Y int
}
// KeyEvent represents an event associated with a keyboard key
type KeyEvent struct {
HandlerEvent
Key Key
@ -31,74 +29,86 @@ type KeyEvent struct {
Duration int
}
// KeyCharsEvent represents an event associated with a keyboard character being pressed
type KeyCharsEvent struct {
HandlerEvent
Chars []rune
}
// KeyDownHandler represents a handler for a keyboard key pressed event
type KeyDownHandler interface {
OnKeyDown(event KeyEvent) bool
}
// KeyRepeatHandler represents a handler for a keyboard key held-down event; between a pressed and released.
type KeyRepeatHandler interface {
OnKeyRepeat(event KeyEvent) bool
}
// KeyUpHandler represents a handler for a keyboard key release event
type KeyUpHandler interface {
OnKeyUp(event KeyEvent) bool
}
// KeyCharsHandler represents a handler associated with a keyboard character pressed event
type KeyCharsHandler interface {
OnKeyChars(event KeyCharsEvent) bool
}
// MouseEvent represents a mouse event
type MouseEvent struct {
HandlerEvent
Button MouseButton
}
// MouseEvent represents a mouse movement event
type MouseMoveEvent struct {
HandlerEvent
}
type Handler interface{}
type KeyDownHandler interface {
OnKeyDown(event KeyEvent) bool
}
type KeyRepeatHandler interface {
OnKeyRepeat(event KeyEvent) bool
}
type KeyUpHandler interface {
OnKeyUp(event KeyEvent) bool
}
type KeyCharsHandler interface {
OnKeyChars(event KeyCharsEvent) bool
}
// MouseButtonDownHandler represents a handler for a mouse button pressed event
type MouseButtonDownHandler interface {
OnMouseButtonDown(event MouseEvent) bool
}
// MouseButtonRepeatHandler represents a handler for a mouse button held-down event; between a pressed and released.
type MouseButtonRepeatHandler interface {
OnMouseButtonRepeat(event MouseEvent) bool
}
// MouseButtonUpHandler represents a handler for a mouse button release event
type MouseButtonUpHandler interface {
OnMouseButtonUp(event MouseEvent) bool
}
// MouseMoveHandler represents a handler for a mouse button release event
type MouseMoveHandler interface {
OnMouseMove(event MouseMoveEvent) bool
}
var singleton inputManager
// Initialize creates a single global input manager based on a specific input service
func Initialize(inputService InputService) {
singleton = inputManager{
inputService: inputService,
}
}
// Advance moves the input manager with the elapsed number of seconds.
func Advance(elapsed float64) error {
return singleton.advance(elapsed)
}
// BindHandlerWithPriority adds an event handler with a specific call priority
func BindHandlerWithPriority(handler Handler, priority Priority) error {
return singleton.bindHandler(handler, priority)
}
// BindHandler adds an event handler
func BindHandler(handler Handler) error {
return BindHandlerWithPriority(handler, PriorityDefault)
}
// UnbindHandler removes a previously bound event handler
func UnbindHandler(handler Handler) error {
return singleton.unbindHandler(handler)
}

View File

@ -1,12 +1,15 @@
// Package ebiten provides graphics and input API to develop a 2D game.
package ebiten
import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/inpututil"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
)
var (
//nolint:gochecknoglobals This is a constant in all but by name, no constant map in go
keyToEbiten = map[d2input.Key]ebiten.Key{
d2input.Key0: ebiten.Key0,
d2input.Key1: ebiten.Key1,
@ -109,6 +112,7 @@ var (
d2input.KeyControl: ebiten.KeyControl,
d2input.KeyShift: ebiten.KeyShift,
}
//nolint:gochecknoglobals This is a constant in all but by name, no constant map in go
mouseButtonToEbiten = map[d2input.MouseButton]ebiten.MouseButton{
d2input.MouseButtonLeft: ebiten.MouseButtonLeft,
d2input.MouseButtonMiddle: ebiten.MouseButtonMiddle,
@ -119,38 +123,47 @@ var (
// InputService provides an abstraction on ebiten to support handling input events
type InputService struct{}
func (is InputService) CursorPosition() (x int, y int) {
// CursorPosition returns a position of a mouse cursor relative to the game screen (window).
func (is InputService) CursorPosition() (x, y int) {
return ebiten.CursorPosition()
}
// InputChars return "printable" runes read from the keyboard at the time update is called.
func (is InputService) InputChars() []rune {
return ebiten.InputChars()
}
// IsKeyPressed checks if the provided key is down.
func (is InputService) IsKeyPressed(key d2input.Key) bool {
return ebiten.IsKeyPressed(keyToEbiten[key])
}
// IsKeyJustPressed checks if the provided key is just transitioned from up to down.
func (is InputService) IsKeyJustPressed(key d2input.Key) bool {
return inpututil.IsKeyJustPressed(keyToEbiten[key])
}
// IsKeyJustReleased checks if the provided key is just transitioned from down to up.
func (is InputService) IsKeyJustReleased(key d2input.Key) bool {
return inpututil.IsKeyJustReleased(keyToEbiten[key])
}
// IsMouseButtonPressed checks if the provided mouse button is down.
func (is InputService) IsMouseButtonPressed(button d2input.MouseButton) bool {
return ebiten.IsMouseButtonPressed(mouseButtonToEbiten[button])
}
// IsMouseButtonJustPressed checks if the provided mouse button is just transitioned from up to down.
func (is InputService) IsMouseButtonJustPressed(button d2input.MouseButton) bool {
return inpututil.IsMouseButtonJustPressed(mouseButtonToEbiten[button])
}
// IsMouseButtonJustReleased checks if the provided mouse button is just transitioned from down to up.
func (is InputService) IsMouseButtonJustReleased(button d2input.MouseButton) bool {
return inpututil.IsMouseButtonJustReleased(mouseButtonToEbiten[button])
}
// KeyPressDuration returns how long the key is pressed in frames.
func (is InputService) KeyPressDuration(key d2input.Key) int {
return inpututil.KeyPressDuration(keyToEbiten[key])
}

View File

@ -4,36 +4,21 @@ import (
"sort"
)
type handlerEntry struct {
handler Handler
priority Priority
}
// Priority of the event handler
type Priority int
type handlerEntryList []handlerEntry
//noinspection GoUnusedConst
const (
// PriorityLow is a low priority handler
PriorityLow Priority = iota
// PriorityDefault is a default priority handler
PriorityDefault
// PriorityHigh is a high priority handler
PriorityHigh
)
func (lel handlerEntryList) Len() int {
return len(lel)
}
func (lel handlerEntryList) Swap(i, j int) {
lel[i], lel[j] = lel[j], lel[i]
}
func (lel handlerEntryList) Less(i, j int) bool {
return lel[i].priority > lel[j].priority
}
type InputService interface {
CursorPosition() (x int, y int)
InputChars() []rune
IsKeyPressed(key Key) bool
IsKeyJustPressed(key Key) bool
IsKeyJustReleased(key Key) bool
IsMouseButtonPressed(button MouseButton) bool
IsMouseButtonJustPressed(button MouseButton) bool
IsMouseButtonJustReleased(button MouseButton) bool
KeyPressDuration(key Key) int
}
// Handler is an event handler
type Handler interface{}
type inputManager struct {
inputService InputService
@ -126,7 +111,7 @@ func (im *inputManager) advance(_ float64) error {
for button := mouseButtonMin; button <= mouseButtonMax; button++ {
if im.inputService.IsMouseButtonJustPressed(button) {
event := MouseEvent{eventBase, MouseButton(button)}
event := MouseEvent{eventBase, button}
im.propagate(func(handler Handler) bool {
if l, ok := handler.(MouseButtonDownHandler); ok {
return l.OnMouseButtonDown(event)
@ -137,7 +122,7 @@ func (im *inputManager) advance(_ float64) error {
}
if im.inputService.IsMouseButtonJustReleased(button) {
event := MouseEvent{eventBase, MouseButton(button)}
event := MouseEvent{eventBase, button}
im.propagate(func(handler Handler) bool {
if l, ok := handler.(MouseButtonUpHandler); ok {
return l.OnMouseButtonUp(event)
@ -147,7 +132,7 @@ func (im *inputManager) advance(_ float64) error {
})
}
if im.inputService.IsMouseButtonPressed(button) {
event := MouseEvent{eventBase, MouseButton(button)}
event := MouseEvent{eventBase, button}
im.propagate(func(handler Handler) bool {
if l, ok := handler.(MouseButtonRepeatHandler); ok {
return l.OnMouseButtonRepeat(event)
@ -215,3 +200,22 @@ func (im *inputManager) propagate(callback func(Handler) bool) {
priority = entry.priority
}
}
type handlerEntry struct {
handler Handler
priority Priority
}
type handlerEntryList []handlerEntry
func (lel handlerEntryList) Len() int {
return len(lel)
}
func (lel handlerEntryList) Swap(i, j int) {
lel[i], lel[j] = lel[j], lel[i]
}
func (lel handlerEntryList) Less(i, j int) bool {
return lel[i].priority > lel[j].priority
}

View File

@ -0,0 +1,23 @@
package d2input
// InputService represents an interface offering Keyboard and Mouse interactions.
type InputService interface {
// CursorPosition returns a position of a mouse cursor relative to the game screen (window).
CursorPosition() (x int, y int)
// InputChars return "printable" runes read from the keyboard at the time update is called.
InputChars() []rune
// IsKeyPressed checks if the provided key is down.
IsKeyPressed(key Key) bool
// IsKeyJustPressed checks if the provided key is just transitioned from up to down.
IsKeyJustPressed(key Key) bool
// IsKeyJustReleased checks if the provided key is just transitioned from down to up.
IsKeyJustReleased(key Key) bool
// IsMouseButtonPressed checks if the provided mouse button is down.
IsMouseButtonPressed(button MouseButton) bool
// IsMouseButtonJustPressed checks if the provided mouse button is just transitioned from up to down.
IsMouseButtonJustPressed(button MouseButton) bool
// IsMouseButtonJustReleased checks if the provided mouse button is just transitioned from down to up.
IsMouseButtonJustReleased(button MouseButton) bool
// KeyPressDuration returns how long the key is pressed in frames.
KeyPressDuration(key Key) int
}

View File

@ -1,138 +1,225 @@
// Package d2input provides interaction with input services providing key and mouse interactions.
package d2input
// Key is the physical key of keyboard input
// Key represents button on a traditional keyboard.
type Key int
const (
// Key0 is the number 0
Key0 Key = iota
// Key1 is the number 1
Key1
// Key2 is the number 2
Key2
// Key3 is the number 3
Key3
// Key4 is the number 4
Key4
// Key5 is the number 5
Key5
// Key6 is the number 6
Key6
// Key7 is the number 7
Key7
// Key8 is the number 8
Key8
// Key9 is the number 9
Key9
// KeyA is the letter A
KeyA
// KeyB is the letter B
KeyB
// KeyC is the letter C
KeyC
// KeyD is the letter D
KeyD
// KeyE is the letter E
KeyE
// KeyF is the letter F
KeyF
// KeyG is the letter G
KeyG
// KeyH is the letter H
KeyH
// KeyI is the letter I
KeyI
// KeyJ is the letter J
KeyJ
// KeyK is the letter K
KeyK
// KeyL is the letter L
KeyL
// KeyM is the letter M
KeyM
// KeyN is the letter N
KeyN
// KeyO is the letter O
KeyO
// KeyP is the letter P
KeyP
// KeyQ is the letter Q
KeyQ
// KeyR is the letter R
KeyR
// KeyS is the letter S
KeyS
// KeyT is the letter T
KeyT
// KeyU is the letter U
KeyU
// KeyV is the letter V
KeyV
// KeyW is the letter W
KeyW
// KeyX is the letter X
KeyX
// KeyY is the letter Y
KeyY
// KeyZ is the letter Z
KeyZ
// KeyApostrophe is the Apostrophe
KeyApostrophe
// KeyBackslash is the Backslash
KeyBackslash
// KeyBackspace is the Backspace
KeyBackspace
// KeyCapsLock is the CapsLock
KeyCapsLock
// KeyComma is the Comma
KeyComma
// KeyDelete is the Delete
KeyDelete
// KeyDown is the down arrow key
KeyDown
// KeyEnd is the End
KeyEnd
// KeyEnter is the Enter
KeyEnter
// KeyEqual is the Equal
KeyEqual
// KeyEscape is the Escape
KeyEscape
// KeyF1 is the function F1
KeyF1
// KeyF2 is the function F2
KeyF2
// KeyF3 is the function F3
KeyF3
// KeyF4 is the function F4
KeyF4
// KeyF5 is the function F5
KeyF5
// KeyF6 is the function F6
KeyF6
// KeyF7 is the function F7
KeyF7
// KeyF8 is the function F8
KeyF8
// KeyF9 is the function F9
KeyF9
// KeyF10 is the function F10
KeyF10
// KeyF11 is the function F11
KeyF11
// KeyF12 is the function F12
KeyF12
// KeyGraveAccent is the Grave Accent
KeyGraveAccent
// KeyHome is the home key
KeyHome
// KeyInsert is the insert key
KeyInsert
// KeyKP0 is keypad 0
KeyKP0
// KeyKP1 is keypad 1
KeyKP1
// KeyKP2 is keypad 2
KeyKP2
// KeyKP3 is keypad 3
KeyKP3
// KeyKP4 is keypad 4
KeyKP4
// KeyKP5 is keypad 5
KeyKP5
// KeyKP6 is keypad 6
KeyKP6
// KeyKP7 is keypad 7
KeyKP7
// KeyKP8 is keypad 8
KeyKP8
// KeyKP9 is keypad 9
KeyKP9
// KeyKPAdd is keypad Add
KeyKPAdd
// KeyKPDecimal is keypad Decimal
KeyKPDecimal
// KeyKPDivide is keypad Divide
KeyKPDivide
// KeyKPEnter is keypad Enter
KeyKPEnter
// KeyKPEqual is keypad Equal
KeyKPEqual
// KeyKPMultiply is keypad Multiply
KeyKPMultiply
// KeyKPSubtract is keypad Subtract
KeyKPSubtract
// KeyLeft is the left arrow key
KeyLeft
// KeyLeftBracket is the left bracket
KeyLeftBracket
// KeyMenu is the Menu key
KeyMenu
// KeyMinus is the Minus key
KeyMinus
// KeyNumLock is the NumLock key
KeyNumLock
// KeyPageDown is the PageDown key
KeyPageDown
// KeyPageUp is the PageUp key
KeyPageUp
// KeyPause is the Pause key
KeyPause
// KeyPeriod is the Period key
KeyPeriod
// KeyPrintScreen is the PrintScreen key
KeyPrintScreen
// KeyRight is the right arrow key
KeyRight
// KeyRightBracket is the right bracket key
KeyRightBracket
// KeyScrollLock is the scroll lock key
KeyScrollLock
// KeySemicolon is the semicolon key
KeySemicolon
// KeySlash is the front slash key
KeySlash
// KeySpace is the space key
KeySpace
// KeyTab is the tab key
KeyTab
// KeyUp is the up arrow key
KeyUp
// KeyAlt is the alt key
KeyAlt
// KeyControl is the control key
KeyControl
// KeyShift is the shift key
KeyShift
// Lowest key in key constants
keyMin = Key0
// Highest key is key constants
keyMax = KeyShift
)
// KeyMod represents a "modified" key action. This could mean, for example, ctrl-S
type KeyMod int
const (
// KeyModAlt is the Alt key modifier
KeyModAlt KeyMod = 1 << iota
// KeyModControl is the Control key modifier
KeyModControl
// KeyModShift is the Shift key modifier
KeyModShift
)
// MouseButton is the physical button for mouse input
type MouseButton int
const (
MouseButtonLeft MouseButton = iota
MouseButtonMiddle
MouseButtonRight
mouseButtonMin = MouseButtonLeft
mouseButtonMax = MouseButtonRight
)
type MouseButtonMod int
const (
MouseButtonModLeft MouseButtonMod = 1 << iota
MouseButtonModMiddle
MouseButtonModRight
)

View File

@ -0,0 +1,28 @@
package d2input
// MouseButton represents a traditional 3-button mouse
type MouseButton int
const (
// MouseButtonLeft is the left mouse button
MouseButtonLeft MouseButton = iota
// MouseButtonMiddle is the middle mouse button
MouseButtonMiddle
// MouseButtonRight is the right mouse button
MouseButtonRight
mouseButtonMin = MouseButtonLeft
mouseButtonMax = MouseButtonRight
)
// MouseButtonMod represents a "modified" mouse button action. This could mean, for example, ctrl-mouse_left
type MouseButtonMod int
const (
// MouseButtonLeft is a modified left mouse button
MouseButtonModLeft MouseButtonMod = 1 << iota
// MouseButtonModMiddle is a modified middle mouse button
MouseButtonModMiddle
// MouseButtonModRight is a modified right mouse button
MouseButtonModRight
)