From da30a83491de6edccaef69b5f5e8c8251df814a3 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 30 Nov 2013 04:24:52 +0900 Subject: [PATCH] Remove ebiten.GameContext --- ebiten.go | 14 +----- example/game/blank/blank.go | 3 +- example/game/input/input.go | 20 ++++---- example/game/monochrome/monochrome.go | 38 +++++++++++---- example/game/rects/rects.go | 32 +++++++++++-- example/game/rotating/rotating.go | 31 +++++++++++-- example/game/sprites/sprites.go | 32 ++++++++++--- example/game/testpattern/testpattern.go | 3 +- example/main.go | 20 +++++--- ui/cocoa/cocoa.go | 61 ++++++++++++++++--------- 10 files changed, 174 insertions(+), 80 deletions(-) diff --git a/ebiten.go b/ebiten.go index 3e178f3f7..acb63e372 100644 --- a/ebiten.go +++ b/ebiten.go @@ -4,12 +4,6 @@ import ( "github.com/hajimehoshi/go-ebiten/graphics" ) -// TODO: Remove this -type GameContext interface { - ScreenWidth() int - ScreenHeight() int -} - type ScreenSizeUpdatedEvent struct { Width int Height int @@ -20,17 +14,11 @@ type InputStateUpdatedEvent struct { Y int } -type UIEvents interface { - ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent -} - type UI interface { PollEvents() InitTextures(func(graphics.TextureFactory)) Draw(func(graphics.Canvas)) + ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent InputStateUpdated() <-chan InputStateUpdatedEvent - - // TODO: Remove this - Update(func(GameContext)) } diff --git a/example/game/blank/blank.go b/example/game/blank/blank.go index ee2f802b4..f0f35ee7f 100644 --- a/example/game/blank/blank.go +++ b/example/game/blank/blank.go @@ -1,7 +1,6 @@ package blank import ( - "github.com/hajimehoshi/go-ebiten" "github.com/hajimehoshi/go-ebiten/graphics" ) @@ -15,7 +14,7 @@ func New() *Blank { func (game *Blank) InitTextures(tf graphics.TextureFactory) { } -func (game *Blank) Update(context ebiten.GameContext) { +func (game *Blank) Update() { } func (game *Blank) Draw(canvas graphics.Canvas) { diff --git a/example/game/input/input.go b/example/game/input/input.go index b9e232c48..b5790da50 100644 --- a/example/game/input/input.go +++ b/example/game/input/input.go @@ -10,22 +10,22 @@ import ( ) type Input struct { - textTextureId graphics.TextureId - inputStateCh chan ebiten.InputStateUpdatedEvent - x int - y int + textTextureId graphics.TextureId + inputStateUpdatedCh chan ebiten.InputStateUpdatedEvent + x int + y int } func New() *Input { return &Input{ - inputStateCh: make(chan ebiten.InputStateUpdatedEvent, 1), - x: -1, - y: -1, + inputStateUpdatedCh: make(chan ebiten.InputStateUpdatedEvent), + x: -1, + y: -1, } } func (game *Input) InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent { - return game.inputStateCh + return game.inputStateUpdatedCh } func (game *Input) InitTextures(tf graphics.TextureFactory) { @@ -44,11 +44,11 @@ func (game *Input) InitTextures(tf graphics.TextureFactory) { } } -func (game *Input) Update(context ebiten.GameContext) { +func (game *Input) Update() { events: for { select { - case e := <-game.inputStateCh: + case e := <-game.inputStateUpdatedCh: game.x, game.y = e.X, e.Y default: break events diff --git a/example/game/monochrome/monochrome.go b/example/game/monochrome/monochrome.go index 20ff1f6e7..3458588f2 100644 --- a/example/game/monochrome/monochrome.go +++ b/example/game/monochrome/monochrome.go @@ -15,20 +15,28 @@ const ( ) type Monochrome struct { - ebitenTextureId graphics.TextureId - ch chan bool - colorMatrix matrix.Color - geometryMatrix matrix.Geometry + ebitenTextureId graphics.TextureId + ch chan bool + colorMatrix matrix.Color + geometryMatrix matrix.Geometry + screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent + screenWidth int + screenHeight int } func New() *Monochrome { return &Monochrome{ - ch: make(chan bool), - colorMatrix: matrix.IdentityColor(), - geometryMatrix: matrix.IdentityGeometry(), + ch: make(chan bool), + colorMatrix: matrix.IdentityColor(), + geometryMatrix: matrix.IdentityGeometry(), + screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), } } +func (game *Monochrome) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent { + return game.screenSizeUpdatedCh +} + func (game *Monochrome) InitTextures(tf graphics.TextureFactory) { file, err := os.Open("images/ebiten.png") if err != nil { @@ -90,13 +98,23 @@ func (game *Monochrome) update() { } } -func (game *Monochrome) Update(context ebiten.GameContext) { +func (game *Monochrome) Update() { +events: + for { + select { + case e := <-game.screenSizeUpdatedCh: + game.screenWidth, game.screenHeight = e.Width, e.Height + default: + break events + } + } + game.ch <- true <-game.ch game.geometryMatrix = matrix.IdentityGeometry() - tx := context.ScreenWidth()/2 - ebitenTextureWidth/2 - ty := context.ScreenHeight()/2 - ebitenTextureHeight/2 + tx := game.screenWidth/2 - ebitenTextureWidth/2 + ty := game.screenHeight/2 - ebitenTextureHeight/2 game.geometryMatrix.Translate(float64(tx), float64(ty)) } diff --git a/example/game/rects/rects.go b/example/game/rects/rects.go index a0125a49f..e897fecb5 100644 --- a/example/game/rects/rects.go +++ b/example/game/rects/rects.go @@ -17,6 +17,9 @@ type Rects struct { offscreenInited bool rectBounds *graphics.Rect rectColor *color.RGBA + screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent + screenWidth int + screenHeight int } const ( @@ -32,9 +35,14 @@ func New() *Rects { offscreenInited: false, rectBounds: &graphics.Rect{}, rectColor: &color.RGBA{}, + screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), } } +func (game *Rects) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent { + return game.screenSizeUpdatedCh +} + func (game *Rects) InitTextures(tf graphics.TextureFactory) { var err error game.rectTextureId, err = tf.CreateRenderTarget(rectTextureWidth, rectTextureHeight) @@ -61,11 +69,25 @@ func abs(a int) int { return a } -func (game *Rects) Update(context ebiten.GameContext) { - x1 := rand.Intn(context.ScreenWidth()) - x2 := rand.Intn(context.ScreenWidth()) - y1 := rand.Intn(context.ScreenHeight()) - y2 := rand.Intn(context.ScreenHeight()) +func (game *Rects) Update() { +events: + for { + select { + case e := <-game.screenSizeUpdatedCh: + game.screenWidth, game.screenHeight = e.Width, e.Height + default: + break events + } + } + + if game.screenWidth == 0 || game.screenHeight == 0 { + return + } + + x1 := rand.Intn(game.screenWidth) + x2 := rand.Intn(game.screenWidth) + y1 := rand.Intn(game.screenHeight) + y2 := rand.Intn(game.screenHeight) game.rectBounds.X = min(x1, x2) game.rectBounds.Y = min(y1, y2) game.rectBounds.Width = abs(x1 - x2) diff --git a/example/game/rotating/rotating.go b/example/game/rotating/rotating.go index b8dc80079..12ebb82cc 100644 --- a/example/game/rotating/rotating.go +++ b/example/game/rotating/rotating.go @@ -19,10 +19,19 @@ type Rotating struct { ebitenTextureId graphics.TextureId x int geometryMatrix matrix.Geometry + screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent + screenWidth int + screenHeight int } func New() *Rotating { - return &Rotating{} + return &Rotating{ + screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), + } +} + +func (game *Rotating) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent { + return game.screenSizeUpdatedCh } func (game *Rotating) InitTextures(tf graphics.TextureFactory) { @@ -41,7 +50,21 @@ func (game *Rotating) InitTextures(tf graphics.TextureFactory) { } } -func (game *Rotating) Update(context ebiten.GameContext) { +func (game *Rotating) Update() { +events: + for { + select { + case e := <-game.screenSizeUpdatedCh: + game.screenWidth, game.screenHeight = e.Width, e.Height + default: + break events + } + } + + if game.screenWidth == 0 || game.screenHeight == 0 { + return + } + const fps = 60 game.x++ @@ -51,8 +74,8 @@ func (game *Rotating) Update(context ebiten.GameContext) { game.geometryMatrix.Translate(-tx/2, -ty/2) game.geometryMatrix.Rotate(float64(game.x) * 2 * math.Pi / float64(fps*10)) game.geometryMatrix.Translate(tx/2, ty/2) - centerX := float64(context.ScreenWidth()) / 2 - centerY := float64(context.ScreenHeight()) / 2 + centerX := float64(game.screenWidth) / 2 + centerY := float64(game.screenHeight) / 2 game.geometryMatrix.Translate(centerX-tx/2, centerY-ty/2) } diff --git a/example/game/sprites/sprites.go b/example/game/sprites/sprites.go index 8009db35f..3b3fcfb2d 100644 --- a/example/game/sprites/sprites.go +++ b/example/game/sprites/sprites.go @@ -66,13 +66,19 @@ func (sprite *Sprite) Update() { type Sprites struct { ebitenTextureId graphics.TextureId sprites []*Sprite + screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent + screenWidth int + screenHeight int } func New() *Sprites { - go func() { + return &Sprites{ + screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), + } +} - }() - return &Sprites{} +func (game *Sprites) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent { + return game.screenSizeUpdatedCh } func (game *Sprites) InitTextures(tf graphics.TextureFactory) { @@ -91,13 +97,27 @@ func (game *Sprites) InitTextures(tf graphics.TextureFactory) { } } -func (game *Sprites) Update(context ebiten.GameContext) { +func (game *Sprites) Update() { +events: + for { + select { + case e := <-game.screenSizeUpdatedCh: + game.screenWidth, game.screenHeight = e.Width, e.Height + default: + break events + } + } + + if game.screenWidth == 0 || game.screenHeight == 0 { + return + } + if game.sprites == nil { game.sprites = []*Sprite{} for i := 0; i < 100; i++ { sprite := newSprite( - context.ScreenWidth(), - context.ScreenHeight(), + game.screenWidth, + game.screenHeight, ebitenTextureWidth, ebitenTextureHeight) game.sprites = append(game.sprites, sprite) diff --git a/example/game/testpattern/testpattern.go b/example/game/testpattern/testpattern.go index 78f45cabe..2097ce76a 100644 --- a/example/game/testpattern/testpattern.go +++ b/example/game/testpattern/testpattern.go @@ -1,7 +1,6 @@ package testpattern import ( - "github.com/hajimehoshi/go-ebiten" "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/matrix" "image" @@ -40,7 +39,7 @@ func (game *TestPattern) InitTextures(tf graphics.TextureFactory) { game.textureHeight = size.Y } -func (game *TestPattern) Update(context ebiten.GameContext) { +func (game *TestPattern) Update() { geo := matrix.IdentityGeometry() geo.Translate(13, 13) game.geos = append(game.geos, geo) diff --git a/example/main.go b/example/main.go index 8f131d089..f564e4eeb 100644 --- a/example/main.go +++ b/example/main.go @@ -19,7 +19,7 @@ import ( type Game interface { InitTextures(tf graphics.TextureFactory) - Update(context ebiten.GameContext) + Update() Draw(canvas graphics.Canvas) } @@ -66,25 +66,33 @@ func main() { tick := time.Tick(frameTime) for { <-tick - ui.Update(func(c ebiten.GameContext) { + func() { lock.Lock() defer lock.Unlock() - game.Update(c) - }) + game.Update() + }() } }() inputStateUpdated := ui.InputStateUpdated() + screenSizeUpdated := ui.ScreenSizeUpdated() for { ui.PollEvents() events: for { select { + case e := <-screenSizeUpdated: + type Handler interface { + ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent + } + if game2, ok := game.(Handler); ok { + game2.ScreenSizeUpdated() <- e + } case e := <-inputStateUpdated: - type InputStateUpdatedHandler interface { + type Handler interface { InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent } - if game2, ok := game.(InputStateUpdatedHandler); ok { + if game2, ok := game.(Handler); ok { game2.InputStateUpdated() <- e } default: diff --git a/ui/cocoa/cocoa.go b/ui/cocoa/cocoa.go index 73d3d8fb4..d92e24b60 100644 --- a/ui/cocoa/cocoa.go +++ b/ui/cocoa/cocoa.go @@ -27,28 +27,17 @@ func init() { runtime.LockOSThread() } -type GameContext struct { - screenWidth int - screenHeight int -} - -func (context *GameContext) ScreenWidth() int { - return context.screenWidth -} - -func (context *GameContext) ScreenHeight() int { - return context.screenHeight -} - type UI struct { screenWidth int screenHeight int screenScale int graphicsDevice *opengl.Device - gameContext *GameContext window unsafe.Pointer + initialEventSent bool inputStateUpdatedChs chan chan ebiten.InputStateUpdatedEvent inputStateUpdatedNotified chan ebiten.InputStateUpdatedEvent + screenSizeUpdatedChs chan chan ebiten.ScreenSizeUpdatedEvent + screenSizeUpdatedNotified chan ebiten.ScreenSizeUpdatedEvent } var currentUI *UI @@ -61,12 +50,11 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI { screenWidth: screenWidth, screenHeight: screenHeight, screenScale: screenScale, - gameContext: &GameContext{ - screenWidth: screenWidth, - screenHeight: screenHeight, - }, + initialEventSent: false, inputStateUpdatedChs: make(chan chan ebiten.InputStateUpdatedEvent), inputStateUpdatedNotified: make(chan ebiten.InputStateUpdatedEvent), + screenSizeUpdatedChs: make(chan chan ebiten.ScreenSizeUpdatedEvent), + screenSizeUpdatedNotified: make(chan ebiten.ScreenSizeUpdatedEvent), } cTitle := C.CString(title) @@ -94,6 +82,7 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI { func (ui *UI) chLoop() { inputStateUpdated := []chan ebiten.InputStateUpdatedEvent{} + screenSizeUpdated := []chan ebiten.ScreenSizeUpdatedEvent{} for { select { case ch := <-ui.inputStateUpdatedChs: @@ -102,12 +91,23 @@ func (ui *UI) chLoop() { for _, ch := range inputStateUpdated { ch <- e } + case ch := <-ui.screenSizeUpdatedChs: + screenSizeUpdated = append(screenSizeUpdated, ch) + case e := <-ui.screenSizeUpdatedNotified: + for _, ch := range screenSizeUpdated { + ch <- e + } } } } func (ui *UI) PollEvents() { C.PollEvents() + if !ui.initialEventSent { + e := ebiten.ScreenSizeUpdatedEvent{ui.screenWidth, ui.screenHeight} + ui.notifyScreenSizeUpdated(e) + ui.initialEventSent = true + } } func (ui *UI) InitTextures(f func(graphics.TextureFactory)) { @@ -116,10 +116,6 @@ func (ui *UI) InitTextures(f func(graphics.TextureFactory)) { C.EndDrawing(ui.window) } -func (ui *UI) Update(f func(ebiten.GameContext)) { - f(ui.gameContext) -} - func (ui *UI) Draw(f func(graphics.Canvas)) { C.BeginDrawing(ui.window) ui.graphicsDevice.Update(f) @@ -140,6 +136,27 @@ func (ui *UI) notifyInputStateUpdated(e ebiten.InputStateUpdatedEvent) { }() } +func (ui *UI) ScreenSizeUpdated() <-chan ebiten.ScreenSizeUpdatedEvent { + ch := make(chan ebiten.ScreenSizeUpdatedEvent) + go func() { + ui.screenSizeUpdatedChs <- ch + }() + return ch +} + +func (ui *UI) notifyScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { + go func() { + ui.screenSizeUpdatedNotified <- e + }() +} + +//export ebiten_ScreenSizeUpdated +func ebiten_ScreenSizeUpdated(width, height int) { + ui := currentUI + e := ebiten.ScreenSizeUpdatedEvent{width, height} + ui.notifyScreenSizeUpdated(e) +} + //export ebiten_InputUpdated func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) { ui := currentUI