ebiten: refactoring: remove imageDumperGame

This enables passing the user's Game to internal/ui without wrapping.

This is necessary to check whether the user's Game implements an
optional function or not.

Updates #2046
This commit is contained in:
Hajime Hoshi 2022-10-14 02:55:04 +09:00
parent 25ae96db89
commit f15536e8de
5 changed files with 25 additions and 46 deletions

View File

@ -79,6 +79,7 @@ type gameForUI struct {
offscreen *Image offscreen *Image
screen *Image screen *Image
screenShader *Shader screenShader *Shader
imageDumper imageDumper
} }
func newGameForUI(game Game) *gameForUI { func newGameForUI(game Game) *gameForUI {
@ -129,11 +130,21 @@ func (g *gameForUI) Layout(outsideWidth, outsideHeight int) (int, int) {
} }
func (g *gameForUI) Update() error { func (g *gameForUI) Update() error {
return g.game.Update() if err := g.game.Update(); err != nil {
return err
}
if err := g.imageDumper.update(); err != nil {
return err
}
return nil
} }
func (g *gameForUI) DrawOffscreen() { func (g *gameForUI) DrawOffscreen() error {
g.game.Draw(g.offscreen) g.game.Draw(g.offscreen)
if err := g.imageDumper.dump(g.offscreen); err != nil {
return err
}
return nil
} }
func (g *gameForUI) DrawScreen() { func (g *gameForUI) DrawScreen() {

View File

@ -18,11 +18,11 @@
package ebiten package ebiten
type imageDumper struct { type imageDumper struct {
g Game
} }
func (i *imageDumper) update() error { func (i *imageDumper) update() error {
return i.g.Update() // Do nothing
return nil
} }
func (i *imageDumper) dump(screen *Image) error { func (i *imageDumper) dump(screen *Image) error {

View File

@ -57,8 +57,6 @@ func dumpInternalImages() error {
} }
type imageDumper struct { type imageDumper struct {
g Game
keyState map[Key]int keyState map[Key]int
hasScreenshotKey bool hasScreenshotKey bool
@ -93,10 +91,6 @@ func (i *imageDumper) update() error {
return i.err return i.err
} }
if err := i.g.Update(); err != nil {
return err
}
// If keyState is nil, all values are not initialized. // If keyState is nil, all values are not initialized.
if i.keyState == nil { if i.keyState == nil {
i.keyState = map[Key]int{} i.keyState = map[Key]int{}

View File

@ -38,7 +38,7 @@ type Game interface {
NewScreenImage(width, height int) *Image NewScreenImage(width, height int) *Image
Layout(outsideWidth, outsideHeight int) (int, int) Layout(outsideWidth, outsideHeight int) (int, int)
Update() error Update() error
DrawOffscreen() DrawOffscreen() error
DrawScreen() DrawScreen()
ScreenScaleAndOffsets() (scale, offsetX, offsetY float64) ScreenScaleAndOffsets() (scale, offsetX, offsetY float64)
} }
@ -143,14 +143,16 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
} }
// Draw the game. // Draw the game.
c.drawGame(graphicsDriver) if err := c.drawGame(graphicsDriver); err != nil {
return err
}
// All the vertices data are consumed at the end of the frame, and the data backend can be // All the vertices data are consumed at the end of the frame, and the data backend can be
// available after that. Until then, lock the vertices backend. // available after that. Until then, lock the vertices backend.
return nil return nil
} }
func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics) { func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics) error {
if c.offscreen.volatile != theGlobalState.isScreenClearedEveryFrame() { if c.offscreen.volatile != theGlobalState.isScreenClearedEveryFrame() {
w, h := c.offscreen.width, c.offscreen.height w, h := c.offscreen.width, c.offscreen.height
c.offscreen.MarkDisposed() c.offscreen.MarkDisposed()
@ -163,7 +165,9 @@ func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics) {
if theGlobalState.isScreenClearedEveryFrame() { if theGlobalState.isScreenClearedEveryFrame() {
c.offscreen.clear() c.offscreen.clear()
} }
c.game.DrawOffscreen() if err := c.game.DrawOffscreen(); err != nil {
return err
}
if graphicsDriver.NeedsClearingScreen() { if graphicsDriver.NeedsClearingScreen() {
// This clear is needed for fullscreen mode or some mobile platforms (#622). // This clear is needed for fullscreen mode or some mobile platforms (#622).
@ -171,6 +175,7 @@ func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics) {
} }
c.game.DrawScreen() c.game.DrawScreen()
return nil
} }
func (c *context) layoutGame(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int) { func (c *context) layoutGame(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int) {

33
run.go
View File

@ -143,35 +143,6 @@ func IsScreenFilterEnabled() bool {
return isScreenFilterEnabled() return isScreenFilterEnabled()
} }
type imageDumperGame struct {
game Game
d *imageDumper
err error
}
func (i *imageDumperGame) Update() error {
if i.err != nil {
return i.err
}
if i.d == nil {
i.d = &imageDumper{g: i.game}
}
return i.d.update()
}
func (i *imageDumperGame) Draw(screen *Image) {
if i.err != nil {
return
}
i.game.Draw(screen)
i.err = i.d.dump(screen)
}
func (i *imageDumperGame) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return i.game.Layout(outsideWidth, outsideHeight)
}
// Termination is a special error which indicates Game termination without error. // Termination is a special error which indicates Game termination without error.
var Termination = ui.RegularTermination var Termination = ui.RegularTermination
@ -206,9 +177,7 @@ func RunGame(game Game) error {
defer atomic.StoreInt32(&isRunGameEnded_, 1) defer atomic.StoreInt32(&isRunGameEnded_, 1)
initializeWindowPositionIfNeeded(WindowSize()) initializeWindowPositionIfNeeded(WindowSize())
g := newGameForUI(&imageDumperGame{ g := newGameForUI(game)
game: game,
})
if err := ui.Get().Run(g); err != nil { if err := ui.Get().Run(g); err != nil {
if errors.Is(err, Termination) { if errors.Is(err, Termination) {
return nil return nil