lazarus/platform/platform.go

130 lines
2.1 KiB
Go

package platform
import (
"errors"
"runtime"
"github.com/go-gl/gl/v2.1/gl"
"github.com/veandco/go-sdl2/sdl"
)
var (
ErrAlreadyInit = errors.New("platform is already initialized")
ErrWasNotInit = errors.New("platform was not initialized")
)
var singleton struct {
isInit bool
windows []*Window
}
type Handle uintptr
type Scene interface {
Init(window *Window) error
Advance(window *Window) error
Shutdown(window *Window) error
}
func Init() error {
if singleton.isInit {
return ErrAlreadyInit
}
runtime.LockOSThread()
if err := sdl.Init(sdl.INIT_VIDEO); err != nil {
return err
}
if err := gl.Init(); err != nil {
return err
}
singleton.isInit = true
return nil
}
func Advance() (bool, error) {
if !singleton.isInit {
return false, ErrWasNotInit
}
advanceWindows()
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch event.(type) {
case *sdl.QuitEvent:
return false, nil
default:
if err := processWindowEvents(event); err != nil {
return false, err
}
}
}
return true, nil
}
func Shutdown() error {
if !singleton.isInit {
return ErrWasNotInit
}
for _, w := range singleton.windows {
if err := w.Destroy(); err != nil {
return err
}
}
singleton.windows = nil
singleton.isInit = false
return nil
}
func CreateWindow(title string, width, height int, scene Scene) (*Window, error) {
if !singleton.isInit {
return nil, ErrWasNotInit
}
w, err := newWindow(title, width, height, scene)
if err != nil {
return nil, err
}
appendWindow(w)
return w, err
}
func appendWindow(window *Window) {
singleton.windows = append(singleton.windows, window)
}
func removeWindow(window *Window) bool {
for i, w := range singleton.windows {
if w == window {
singleton.windows = append(singleton.windows[:i], singleton.windows[i+1:]...)
return true
}
}
return false
}
func advanceWindows() {
for _, window := range singleton.windows {
window.advance()
}
}
func processWindowEvents(event sdl.Event) error {
for _, window := range singleton.windows {
if _, err := window.processEvent(event); err != nil {
return err
}
}
return nil
}