project-ely/internal/game/window/input.go

76 lines
1.5 KiB
Go

package window
import (
"context"
"sync"
"github.com/veandco/go-sdl2/sdl"
)
type inputHandler struct {
ctx context.Context
keyboardChan chan sdl.KeyboardEvent
// The actual internal state
mxKeyboard sync.RWMutex
keystates map[sdl.Keycode]bool
// TODO joystick/gamepad
// mxJoystick sync.RWMutex
}
func NewInputHandler(ctx context.Context) *inputHandler {
keyboardChan := make(chan sdl.KeyboardEvent)
keystates := make(map[sdl.Keycode]bool)
i := inputHandler{
ctx: ctx,
keystates: keystates,
keyboardChan: keyboardChan,
}
return &i
}
func (i *inputHandler) CloseChannels() {
close(i.keyboardChan)
}
func (i *inputHandler) KeyboardChan() chan sdl.KeyboardEvent {
return i.keyboardChan
}
func (i *inputHandler) Run() {
running := true
for running {
select {
case event := <-i.keyboardChan:
i.UpdateKeyboard(event)
case <-i.ctx.Done():
running = false
}
}
// Finish up anything in the queues
for e := range i.keyboardChan {
i.UpdateKeyboard(e)
}
}
func (i *inputHandler) UpdateKeyboard(e sdl.KeyboardEvent) {
i.mxKeyboard.Lock()
defer i.mxKeyboard.Unlock()
// Key states (just set a boolean whether the key is actively being pressed)
if e.Type == sdl.KEYDOWN {
i.keystates[e.Keysym.Sym] = true
} else if e.Type == sdl.KEYUP {
i.keystates[e.Keysym.Sym] = false
}
}
func (i *inputHandler) Keystate(keycode sdl.Keycode) bool {
i.mxKeyboard.RLock()
defer i.mxKeyboard.RUnlock()
return i.keystates[keycode]
}