zntg/allg5/event.go
2018-09-22 16:31:09 +02:00

196 lines
4.8 KiB
Go

package allg5
// #include <allegro5/allegro.h>
import "C"
import (
"errors"
"unsafe"
)
type EventQueue struct {
queue *C.ALLEGRO_EVENT_QUEUE
}
type Event interface {
Stamp() float64
}
type EventBase struct {
stamp float64
}
func (eb EventBase) Stamp() float64 {
return eb.stamp
}
type DisplayCloseEvent struct {
EventBase
}
type DisplayResizeEvent struct {
EventBase
X, Y int
Width int
Height int
}
type DisplayOrientation int
const (
DisplayOrientation0Degrees DisplayOrientation = iota
DisplayOrientation90Degrees
DisplayOrientation180Degrees
DisplayOrientation270Degrees
DisplayOrientationFaceUp
DisplayOrientationFaceDown
)
func toDisplayOrientation(o C.int) DisplayOrientation {
switch o {
case C.ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES:
return DisplayOrientation0Degrees
case C.ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES:
return DisplayOrientation90Degrees
case C.ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES:
return DisplayOrientation180Degrees
case C.ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES:
return DisplayOrientation270Degrees
case C.ALLEGRO_DISPLAY_ORIENTATION_FACE_UP:
return DisplayOrientationFaceUp
case C.ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN:
return DisplayOrientationFaceDown
default:
panic("not supported")
}
}
type DisplayOrientationEvent struct {
EventBase
Orientation DisplayOrientation
}
type KeyEvent struct {
EventBase
KeyCode Key
Display *Display
}
type KeyCharEvent struct {
KeyEvent
UnicodeCharacter rune
Modifiers KeyMod
Repeat bool
}
type KeyDownEvent struct {
KeyEvent
}
type KeyUpEvent struct {
KeyEvent
}
type MouseButtonDownEvent struct {
MouseEvent
Button MouseButton
Pressure float32
}
type MouseButtonUpEvent struct {
MouseEvent
Button MouseButton
Pressure float32
}
type MouseEvent struct {
EventBase
X, Y int
Z, W int
Display *Display
}
type MouseMoveEvent struct {
MouseEvent
DeltaX, DeltaY int
DeltaZ, DeltaW int
Pressure float32
}
func NewEventQueue() (*EventQueue, error) {
q := C.al_create_event_queue()
if nil == q {
return nil, errors.New("unable to create event queue")
}
return &EventQueue{q}, nil
}
func (eq *EventQueue) register(source *C.ALLEGRO_EVENT_SOURCE) {
C.al_register_event_source(eq.queue, source)
}
func (eq *EventQueue) RegisterDisplay(d *Display) {
eq.register(C.al_get_display_event_source(d.display))
}
func (eq *EventQueue) RegisterMouse() {
eq.register(C.al_get_mouse_event_source())
}
func (eq *EventQueue) RegisterKeyboard() {
eq.register(C.al_get_keyboard_event_source())
}
func (eq *EventQueue) mapEvent(e *C.ALLEGRO_EVENT) Event {
any := (*C.ALLEGRO_ANY_EVENT)(unsafe.Pointer(e))
eb := EventBase{float64(any.timestamp)}
switch any._type {
case C.ALLEGRO_EVENT_DISPLAY_CLOSE:
return &DisplayCloseEvent{eb}
case C.ALLEGRO_EVENT_DISPLAY_ORIENTATION:
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
return &DisplayOrientationEvent{eb, toDisplayOrientation(display.orientation)}
case C.ALLEGRO_EVENT_DISPLAY_RESIZE:
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
C.al_acknowledge_resize(display.source)
return &DisplayResizeEvent{eb, int(display.x), int(display.y), int(display.width), int(display.height)}
case C.ALLEGRO_EVENT_MOUSE_AXES:
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
return &MouseMoveEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}, int(mouse.dx), int(mouse.dy), int(mouse.dz), int(mouse.dw), float32(mouse.pressure)}
case C.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
return &MouseButtonDownEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}, MouseButton(mouse.button), float32(mouse.pressure)}
case C.ALLEGRO_EVENT_MOUSE_BUTTON_UP:
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
return &MouseButtonUpEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}, MouseButton(mouse.button), float32(mouse.pressure)}
case C.ALLEGRO_EVENT_KEY_DOWN:
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
return &KeyDownEvent{KeyEvent{eb, Key(key.keycode), nil}}
case C.ALLEGRO_EVENT_KEY_UP:
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
return &KeyUpEvent{KeyEvent{eb, Key(key.keycode), nil}}
case C.ALLEGRO_EVENT_KEY_CHAR:
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
return &KeyCharEvent{KeyEvent{eb, Key(key.keycode), nil}, rune(key.unichar), KeyMod(key.modifiers), bool(key.repeat)}
}
return nil
}
func (eq *EventQueue) Get() Event {
var event C.ALLEGRO_EVENT
if !bool(C.al_get_next_event(eq.queue, &event)) {
return nil
}
return eq.mapEvent(&event)
}
func (eq *EventQueue) GetWait() Event {
var event C.ALLEGRO_EVENT
C.al_wait_for_event(eq.queue, &event)
return eq.mapEvent(&event)
}
func (eq *EventQueue) Destroy() {
C.al_destroy_event_queue(eq.queue)
}