internal/ui: move more logics to internal/ui

This commit is contained in:
Hajime Hoshi 2022-02-13 20:02:49 +09:00
parent 9b2f0b6c56
commit 08defeeded
6 changed files with 33 additions and 27 deletions

View File

@ -23,18 +23,22 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/clock"
"github.com/hajimehoshi/ebiten/v2/internal/debug"
graphicspkg "github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
)
const DefaultTPS = 60
type Context interface {
UpdateOffscreen(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int)
UpdateFrame(updateCount int, screenScale float64, offsetX, offsetY float64) error
UpdateGame() error
DrawGame(screenScale float64, offsetX, offsetY float64) error
}
type contextImpl struct {
context Context
updateCalled bool
// The following members must be protected by the mutex m.
outsideWidth float64
outsideHeight float64
@ -75,8 +79,27 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
return err
}
// Ensure that Update is called once before Draw so that Update can be used for initialization.
if !c.updateCalled && updateCount == 0 {
updateCount = 1
c.updateCalled = true
}
debug.Logf("Update count per frame: %d\n", updateCount)
// Update the game.
for i := 0; i < updateCount; i++ {
if err := hooks.RunBeforeUpdateHooks(); err != nil {
return err
}
if err := c.context.UpdateGame(); err != nil {
return err
}
Get().resetForTick()
}
// Draw the game.
screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor)
if err := c.context.UpdateFrame(updateCount, screenScale, offsetX, offsetY); err != nil {
if err := c.context.DrawGame(screenScale, offsetX, offsetY); err != nil {
return err
}

View File

@ -74,7 +74,7 @@ func (*UserInterface) ScreenSizeInFullscreen() (int, int) {
return 0, 0
}
func (*UserInterface) ResetForTick() {
func (*UserInterface) resetForTick() {
}
func (*UserInterface) CursorMode() CursorMode {

View File

@ -1349,7 +1349,7 @@ func (u *UserInterface) IsScreenTransparent() bool {
return val
}
func (u *UserInterface) ResetForTick() {
func (u *UserInterface) resetForTick() {
u.input.resetForTick()
u.m.Lock()

View File

@ -636,7 +636,7 @@ func (u *UserInterface) IsScreenTransparent() bool {
return bodyStyle.Get("backgroundColor").Equal(stringTransparent)
}
func (u *UserInterface) ResetForTick() {
func (u *UserInterface) resetForTick() {
u.input.resetForTick()
}

View File

@ -431,7 +431,7 @@ func (u *UserInterface) IsScreenTransparent() bool {
return false
}
func (u *UserInterface) ResetForTick() {
func (u *UserInterface) resetForTick() {
u.input.resetForTick()
}

View File

@ -18,9 +18,7 @@ import (
"fmt"
"sync"
"github.com/hajimehoshi/ebiten/v2/internal/debug"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
"github.com/hajimehoshi/ebiten/v2/internal/ui"
)
@ -29,8 +27,6 @@ type uiContext struct {
offscreen *Image
screen *Image
updateCalled bool
m sync.Mutex
}
@ -88,24 +84,11 @@ func (c *uiContext) setScreenClearedEveryFrame(cleared bool) {
}
}
func (c *uiContext) UpdateFrame(updateCount int, screenScale float64, offsetX, offsetY float64) error {
// Ensure that Update is called once before Draw so that Update can be used for initialization.
if !c.updateCalled && updateCount == 0 {
updateCount = 1
c.updateCalled = true
}
debug.Logf("Update count per frame: %d\n", updateCount)
for i := 0; i < updateCount; i++ {
if err := hooks.RunBeforeUpdateHooks(); err != nil {
return err
}
if err := c.game.Update(); err != nil {
return err
}
ui.Get().ResetForTick()
}
func (c *uiContext) UpdateGame() error {
return c.game.Update()
}
func (c *uiContext) DrawGame(screenScale float64, offsetX, offsetY float64) error {
// Even though updateCount == 0, the offscreen is cleared and Draw is called.
// Draw should not update the game state and then the screen should not be updated without Update, but
// users might want to process something at Draw with the time intervals of FPS.