mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-31 00:07:17 -04:00
198 lines
4.0 KiB
Go
198 lines
4.0 KiB
Go
|
package d2input
|
||
|
|
||
|
import (
|
||
|
"sort"
|
||
|
|
||
|
"github.com/hajimehoshi/ebiten"
|
||
|
"github.com/hajimehoshi/ebiten/inpututil"
|
||
|
)
|
||
|
|
||
|
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
|
||
|
}
|
||
|
|
||
|
type inputManager struct {
|
||
|
cursorX int
|
||
|
cursorY int
|
||
|
|
||
|
buttonMod MouseButtonMod
|
||
|
keyMod KeyMod
|
||
|
|
||
|
entries handlerEntryList
|
||
|
}
|
||
|
|
||
|
func (im *inputManager) advance(elapsed float64) error {
|
||
|
cursorX, cursorY := ebiten.CursorPosition()
|
||
|
|
||
|
im.keyMod = 0
|
||
|
if ebiten.IsKeyPressed(ebiten.KeyAlt) {
|
||
|
im.keyMod |= KeyModAlt
|
||
|
}
|
||
|
if ebiten.IsKeyPressed(ebiten.KeyControl) {
|
||
|
im.keyMod |= KeyModControl
|
||
|
}
|
||
|
if ebiten.IsKeyPressed(ebiten.KeyShift) {
|
||
|
im.keyMod |= KeyModShift
|
||
|
}
|
||
|
|
||
|
im.buttonMod = 0
|
||
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||
|
im.buttonMod |= MouseButtonModLeft
|
||
|
}
|
||
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonMiddle) {
|
||
|
im.buttonMod |= MouseButtonModMiddle
|
||
|
}
|
||
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
|
||
|
im.buttonMod |= MouseButtonModRight
|
||
|
}
|
||
|
|
||
|
eventBase := HandlerEvent{
|
||
|
im.keyMod,
|
||
|
im.buttonMod,
|
||
|
cursorX,
|
||
|
cursorY,
|
||
|
}
|
||
|
|
||
|
for key := ebiten.Key0; key < ebiten.KeyMax; key++ {
|
||
|
if inpututil.IsKeyJustPressed(key) {
|
||
|
event := KeyEvent{eventBase, Key(key)}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(KeyDownHandler); ok {
|
||
|
return l.OnKeyDown(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if ebiten.IsKeyPressed(key) {
|
||
|
event := KeyEvent{eventBase, Key(key)}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(KeyRepeatHandler); ok {
|
||
|
return l.OnKeyRepeat(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if inpututil.IsKeyJustReleased(key) {
|
||
|
event := KeyEvent{eventBase, Key(key)}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(KeyUpHandler); ok {
|
||
|
return l.OnKeyUp(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if chars := ebiten.InputChars(); len(chars) > 0 {
|
||
|
event := KeyCharsEvent{eventBase, chars}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(KeyCharsHandler); ok {
|
||
|
l.OnKeyChars(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
|
||
|
for button := ebiten.MouseButtonLeft; button < ebiten.MouseButtonMiddle; button++ {
|
||
|
if inpututil.IsMouseButtonJustPressed(button) {
|
||
|
event := MouseEvent{eventBase, MouseButton(button)}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(MouseButtonDownHandler); ok {
|
||
|
return l.OnMouseButtonDown(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if inpututil.IsMouseButtonJustReleased(button) {
|
||
|
event := MouseEvent{eventBase, MouseButton(button)}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(MouseButtonUpHandler); ok {
|
||
|
return l.OnMouseButtonUp(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if im.cursorX != cursorX || im.cursorY != cursorY {
|
||
|
event := MouseMoveEvent{eventBase}
|
||
|
im.propagate(func(handler Handler) bool {
|
||
|
if l, ok := handler.(MouseMoveHandler); ok {
|
||
|
return l.OnMouseMove(event)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
|
||
|
im.cursorX, im.cursorY = cursorX, cursorY
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (im *inputManager) bindHandler(handler Handler, priority Priority) error {
|
||
|
for _, entry := range im.entries {
|
||
|
if entry.handler == handler {
|
||
|
return ErrHasReg
|
||
|
}
|
||
|
}
|
||
|
|
||
|
im.entries = append(im.entries, handlerEntry{handler, priority})
|
||
|
sort.Sort(im.entries)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (im *inputManager) unbindHandler(handler Handler) error {
|
||
|
for i, entry := range im.entries {
|
||
|
if entry.handler == handler {
|
||
|
copy(im.entries[i:], im.entries[i+1:])
|
||
|
im.entries = im.entries[:len(im.entries)-1]
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ErrNotReg
|
||
|
}
|
||
|
|
||
|
func (im *inputManager) propagate(callback func(Handler) bool) {
|
||
|
var priority Priority
|
||
|
var handled bool
|
||
|
|
||
|
for _, entry := range im.entries {
|
||
|
if priority > entry.priority && handled {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if callback(entry.handler) {
|
||
|
handled = true
|
||
|
}
|
||
|
|
||
|
priority = entry.priority
|
||
|
}
|
||
|
}
|