Fix the event handling model

This commit is contained in:
Hajime Hoshi 2013-12-03 22:14:51 +09:00
parent f9e5e754b2
commit 79c74273f5
4 changed files with 53 additions and 81 deletions

View File

@ -62,8 +62,8 @@ func main() {
drawing := make(chan *graphics.LazyCanvas)
go func() {
inputStateUpdated := u.ObserveInputStateUpdated()
screenSizeUpdated := u.ObserveScreenSizeUpdated()
inputStateUpdated := u.InputStateUpdated()
screenSizeUpdated := u.ScreenSizeUpdated()
frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime)
@ -78,8 +78,9 @@ func main() {
if game2, ok := game.(Handler); ok {
game2.OnInputStateUpdated(e)
}
} else {
inputStateUpdated = nil
}
inputStateUpdated = u.ObserveInputStateUpdated()
case e, ok := <-screenSizeUpdated:
if ok {
type Handler interface {
@ -88,8 +89,9 @@ func main() {
if game2, ok := game.(Handler); ok {
game2.OnScreenSizeUpdated(e)
}
} else {
screenSizeUpdated = nil
}
screenSizeUpdated = u.ObserveScreenSizeUpdated()
case <-tick:
game.Update()
case canvas := <-drawing:

View File

@ -4,6 +4,7 @@ import (
"image"
)
// TODO: Remove this?
type TextureFactory interface {
CreateRenderTarget(width, height int) (RenderTargetId, error)
CreateTextureFromImage(img image.Image) (TextureId, error)

View File

@ -28,16 +28,14 @@ func init() {
}
type UI struct {
screenWidth int
screenHeight int
screenScale int
graphicsDevice *opengl.Device
window unsafe.Pointer
initialEventSent bool
inputStateUpdatedChs chan chan ui.InputStateUpdatedEvent
inputStateUpdatedNotified chan ui.InputStateUpdatedEvent
screenSizeUpdatedChs chan chan ui.ScreenSizeUpdatedEvent
screenSizeUpdatedNotified chan ui.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
screenScale int
graphicsDevice *opengl.Device
window unsafe.Pointer
initialEventSent bool
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
inputStateUpdated chan ui.InputStateUpdatedEvent // initialized lazily
}
var currentUI *UI
@ -47,14 +45,10 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
panic("UI can't be duplicated.")
}
u := &UI{
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
initialEventSent: false,
inputStateUpdatedChs: make(chan chan ui.InputStateUpdatedEvent),
inputStateUpdatedNotified: make(chan ui.InputStateUpdatedEvent),
screenSizeUpdatedChs: make(chan chan ui.ScreenSizeUpdatedEvent),
screenSizeUpdatedNotified: make(chan ui.ScreenSizeUpdatedEvent),
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
initialEventSent: false,
}
cTitle := C.CString(title)
@ -75,45 +69,9 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
context)
currentUI = u
u.eventLoop()
return u
}
func (u *UI) eventLoop() {
go func() {
inputStateUpdated := []chan ui.InputStateUpdatedEvent{}
for {
select {
case ch := <-u.inputStateUpdatedChs:
inputStateUpdated = append(inputStateUpdated, ch)
case e := <-u.inputStateUpdatedNotified:
for _, ch := range inputStateUpdated {
ch <- e
close(ch)
}
inputStateUpdated = inputStateUpdated[0:0]
}
}
}()
go func() {
screenSizeUpdated := []chan ui.ScreenSizeUpdatedEvent{}
for {
select {
case ch := <-u.screenSizeUpdatedChs:
screenSizeUpdated = append(screenSizeUpdated, ch)
case e := <-u.screenSizeUpdatedNotified:
for _, ch := range screenSizeUpdated {
ch <- e
close(ch)
}
screenSizeUpdated = []chan ui.ScreenSizeUpdatedEvent{}
}
}
}()
}
func (u *UI) PollEvents() {
C.PollEvents()
if !u.initialEventSent {
@ -123,6 +81,10 @@ func (u *UI) PollEvents() {
}
}
func (u *UI) LoadTextures(map[int]string) {
// TODO: Implement
}
func (u *UI) LoadResources(f func(graphics.TextureFactory)) {
C.BeginDrawing(u.window)
f(u.graphicsDevice.TextureFactory())
@ -135,31 +97,37 @@ func (u *UI) Draw(f func(graphics.Canvas)) {
C.EndDrawing(u.window)
}
func (u *UI) ObserveInputStateUpdated() <-chan ui.InputStateUpdatedEvent {
ch := make(chan ui.InputStateUpdatedEvent)
go func() {
u.inputStateUpdatedChs <- ch
}()
return ch
}
func (u *UI) notifyInputStateUpdated(e ui.InputStateUpdatedEvent) {
go func() {
u.inputStateUpdatedNotified <- e
}()
}
func (u *UI) ObserveScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
ch := make(chan ui.ScreenSizeUpdatedEvent)
go func() {
u.screenSizeUpdatedChs <- ch
}()
return ch
func (u *UI) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
if u.screenSizeUpdated != nil {
return u.screenSizeUpdated
}
u.screenSizeUpdated = make(chan ui.ScreenSizeUpdatedEvent)
return u.screenSizeUpdated
}
func (u *UI) notifyScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
if u.screenSizeUpdated == nil {
return
}
go func() {
u.screenSizeUpdatedNotified <- e
u.screenSizeUpdated <- e
}()
}
func (u *UI) InputStateUpdated() <-chan ui.InputStateUpdatedEvent {
if u.inputStateUpdated != nil {
return u.inputStateUpdated
}
u.inputStateUpdated = make(chan ui.InputStateUpdatedEvent)
return u.inputStateUpdated
}
func (u *UI) notifyInputStateUpdated(e ui.InputStateUpdatedEvent) {
if u.inputStateUpdated == nil {
return
}
go func() {
u.inputStateUpdated <- e
}()
}

View File

@ -15,13 +15,14 @@ type InputStateUpdatedEvent struct {
}
type UIEvents interface {
ObserveScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
ObserveInputStateUpdated() <-chan InputStateUpdatedEvent
ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
InputStateUpdated() <-chan InputStateUpdatedEvent
}
type UI interface {
PollEvents()
LoadResources(func(graphics.TextureFactory))
LoadTextures(map[int]string)
Draw(func(graphics.Canvas))
UIEvents
}