Refactoring event handling

This commit is contained in:
Hajime Hoshi 2013-12-16 09:39:49 +09:00
parent aeab5f3437
commit 94ecfbba9c
9 changed files with 56 additions and 160 deletions

View File

@ -60,22 +60,21 @@ func NewGame() *Game {
}
}
func (game *Game) OnTextureCreated(e graphics.TextureCreatedEvent) {
if e.Error != nil {
panic(e.Error)
func (game *Game) HandleEvent(e interface{}) {
switch e := e.(type) {
case graphics.TextureCreatedEvent:
if e.Error != nil {
panic(e.Error)
}
game.textures[e.Tag.(string)] = e.Id
case graphics.RenderTargetCreatedEvent:
if e.Error != nil {
panic(e.Error)
}
game.renderTargets[e.Tag.(string)] = e.Id
case ui.MouseStateUpdatedEvent:
game.mouseX, game.mouseY = e.X, e.Y
}
game.textures[e.Tag.(string)] = e.Id
}
func (game *Game) OnRenderTargetCreated(e graphics.RenderTargetCreatedEvent) {
if e.Error != nil {
panic(e.Error)
}
game.renderTargets[e.Tag.(string)] = e.Id
}
func (game *Game) OnMouseStateUpdated(e ui.MouseStateUpdatedEvent) {
game.mouseX, game.mouseY = e.X, e.Y
}
func (game *Game) isInitialized() bool {

View File

@ -2,6 +2,7 @@ package main
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/ui"
"github.com/hajimehoshi/go-ebiten/ui/cocoa"
"image"
_ "image/png"
@ -35,12 +36,11 @@ func main() {
const fps = 60
const title = "Ebiten Demo"
ui := cocoa.UI()
u := cocoa.UI()
textureFactory := cocoa.TextureFactory()
window := ui.CreateWindow(screenWidth, screenHeight, screenScale, title)
window := u.CreateWindow(screenWidth, screenHeight, screenScale, title)
textureCreated := textureFactory.TextureCreated()
renderTargetCreated := textureFactory.RenderTargetCreated()
textureFactoryEvents := textureFactory.Events()
for tag, path := range TexturePaths {
tag := tag
@ -67,26 +67,19 @@ func main() {
go func() {
defer close(quit)
mouseStateUpdated := window.MouseStateUpdated()
screenSizeUpdated := window.ScreenSizeUpdated()
windowClosed := window.WindowClosed()
windowEvents := window.Events()
game := NewGame()
frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime)
for {
select {
case e := <-textureCreated:
game.OnTextureCreated(e)
case e := <-renderTargetCreated:
game.OnRenderTargetCreated(e)
case e := <-mouseStateUpdated:
game.OnMouseStateUpdated(e)
case _, ok := <-screenSizeUpdated:
if !ok {
screenSizeUpdated = nil
case e := <-textureFactoryEvents:
game.HandleEvent(e)
case e := <-windowEvents:
if _, ok := e.(ui.WindowClosedEvent); ok {
return
}
case <-windowClosed:
return
game.HandleEvent(e)
case <-tick:
game.Update()
case context := <-drawing:
@ -97,7 +90,7 @@ func main() {
}()
for {
ui.PollEvents()
u.PollEvents()
select {
default:
drawing <- graphics.NewLazyContext()
@ -107,7 +100,7 @@ func main() {
context.Flush(actualContext)
})
after := time.After(time.Duration(int64(time.Second) / 120))
ui.PollEvents()
u.PollEvents()
<-after
case <-quit:
return

View File

@ -16,13 +16,8 @@ type RenderTargetCreatedEvent struct {
Error error
}
type TextureFactoryEvents interface {
TextureCreated() <-chan TextureCreatedEvent
RenderTargetCreated() <-chan RenderTargetCreatedEvent
}
type TextureFactory interface {
CreateRenderTarget(tag interface{}, width, height int)
CreateTexture(tag interface{}, img image.Image)
TextureFactoryEvents
Events() <-chan interface{}
}

View File

@ -14,7 +14,6 @@ type textureFactory struct {
sharedContext unsafe.Pointer
funcs chan func()
funcsDone chan struct{}
textureFactoryEvents
}
func runTextureFactory() *textureFactory {

View File

@ -1,44 +0,0 @@
package cocoa
import (
"github.com/hajimehoshi/go-ebiten/graphics"
)
type textureFactoryEvents struct {
textureCreated chan graphics.TextureCreatedEvent
renderTargetCreated chan graphics.RenderTargetCreatedEvent
}
func (t *textureFactoryEvents) TextureCreated() <-chan graphics.TextureCreatedEvent {
if t.textureCreated != nil {
return t.textureCreated
}
t.textureCreated = make(chan graphics.TextureCreatedEvent)
return t.textureCreated
}
func (t *textureFactoryEvents) notifyTextureCreated(e graphics.TextureCreatedEvent) {
if t.textureCreated == nil {
return
}
go func() {
t.textureCreated <- e
}()
}
func (t *textureFactoryEvents) RenderTargetCreated() <-chan graphics.RenderTargetCreatedEvent {
if t.renderTargetCreated != nil {
return t.renderTargetCreated
}
t.renderTargetCreated = make(chan graphics.RenderTargetCreatedEvent)
return t.renderTargetCreated
}
func (t *textureFactoryEvents) notifyRenderTargetCreated(e graphics.RenderTargetCreatedEvent) {
if t.renderTargetCreated == nil {
return
}
go func() {
t.renderTargetCreated <- e
}()
}

View File

@ -16,6 +16,7 @@ import (
type cocoaUI struct {
textureFactory *textureFactory
textureFactoryEvents chan interface{}
graphicsDevice *opengl.Device
}
@ -54,12 +55,12 @@ func (u *cocoaUI) PollEvents() {
C.PollEvents()
}
func (u *cocoaUI) TextureCreated() <-chan graphics.TextureCreatedEvent {
return u.textureFactory.TextureCreated()
}
func (u *cocoaUI) RenderTargetCreated() <-chan graphics.RenderTargetCreatedEvent {
return u.textureFactory.RenderTargetCreated()
func (u *cocoaUI) Events() <-chan interface{} {
if u.textureFactoryEvents != nil {
return u.textureFactoryEvents
}
u.textureFactoryEvents = make(chan interface{})
return u.textureFactoryEvents
}
func (u *cocoaUI) CreateTexture(tag interface{}, img image.Image) {
@ -74,7 +75,7 @@ func (u *cocoaUI) CreateTexture(tag interface{}, img image.Image) {
Id: id,
Error: err,
}
u.textureFactory.notifyTextureCreated(e)
u.textureFactoryEvents <- e
}()
}
@ -90,6 +91,6 @@ func (u *cocoaUI) CreateRenderTarget(tag interface{}, width, height int) {
Id: id,
Error: err,
}
u.textureFactory.notifyRenderTargetCreated(e)
u.textureFactoryEvents <- e
}()
}

View File

@ -31,7 +31,7 @@ type Window struct {
context *opengl.Context
funcs chan func()
funcsDone chan struct{}
windowEvents
events chan interface{}
}
var windows = map[unsafe.Pointer]*Window{}
@ -97,6 +97,23 @@ func (w *Window) useGLContext(f func()) {
<-w.funcsDone
}
func (w *Window) Events() <-chan interface{} {
if w.events != nil {
return w.events
}
w.events = make(chan interface{})
return w.events
}
func (w *Window) notify(e interface{}) {
if w.events == nil {
return
}
go func() {
w.events <- e
}()
}
/*//export ebiten_ScreenSizeUpdated
func ebiten_ScreenSizeUpdated(nativeWindow unsafe.Pointer, width, height int) {
u := currentUI

View File

@ -1,58 +0,0 @@
package cocoa
import (
"github.com/hajimehoshi/go-ebiten/ui"
)
type windowEvents struct {
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
mouseStateUpdated chan ui.MouseStateUpdatedEvent // initialized lazily
windowClosed chan ui.WindowClosedEvent // initialized lazily
}
func (w *windowEvents) notify(e interface{}) {
go func() {
w.doNotify(e)
}()
}
func (w *windowEvents) doNotify(e interface{}) {
switch e := e.(type) {
case ui.ScreenSizeUpdatedEvent:
if w.screenSizeUpdated != nil {
w.screenSizeUpdated <- e
}
case ui.MouseStateUpdatedEvent:
if w.mouseStateUpdated != nil {
w.mouseStateUpdated <- e
}
case ui.WindowClosedEvent:
if w.windowClosed != nil {
w.windowClosed <- e
}
}
}
func (w *windowEvents) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
if w.screenSizeUpdated != nil {
return w.screenSizeUpdated
}
w.screenSizeUpdated = make(chan ui.ScreenSizeUpdatedEvent)
return w.screenSizeUpdated
}
func (w *windowEvents) MouseStateUpdated() <-chan ui.MouseStateUpdatedEvent {
if w.mouseStateUpdated != nil {
return w.mouseStateUpdated
}
w.mouseStateUpdated = make(chan ui.MouseStateUpdatedEvent)
return w.mouseStateUpdated
}
func (w *windowEvents) WindowClosed() <-chan ui.WindowClosedEvent {
if w.windowClosed != nil {
return w.windowClosed
}
w.windowClosed = make(chan ui.WindowClosedEvent)
return w.windowClosed
}

View File

@ -35,13 +35,7 @@ type UI interface {
CreateWindow(screenWidth, screenHeight, screenScale int, title string) Window
}
type WindowEvents interface {
ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
MouseStateUpdated() <-chan MouseStateUpdatedEvent
WindowClosed() <-chan WindowClosedEvent
}
type Window interface {
Draw(func(graphics.Context))
WindowEvents
Events() <-chan interface{}
}