internal/ui: rename types and members: uiContext -> gameForUI

This commit is contained in:
Hajime Hoshi 2022-02-13 20:18:41 +09:00
parent 29382b424b
commit 0c1c40995c
10 changed files with 55 additions and 55 deletions

View File

@ -21,7 +21,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
) )
type uiContext struct { type gameForUI struct {
game Game game Game
offscreen *Image offscreen *Image
screen *Image screen *Image
@ -29,15 +29,15 @@ type uiContext struct {
m sync.Mutex m sync.Mutex
} }
var theUIContext = &uiContext{} var theGameForUI = &gameForUI{}
func (c *uiContext) set(game Game) { func (c *gameForUI) set(game Game) {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
c.game = game c.game = game
} }
func (c *uiContext) UpdateOffscreen(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int) { func (c *gameForUI) Layout(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int) {
ow, oh := c.game.Layout(int(outsideWidth), int(outsideHeight)) ow, oh := c.game.Layout(int(outsideWidth), int(outsideHeight))
if ow <= 0 || oh <= 0 { if ow <= 0 || oh <= 0 {
panic("ebiten: Layout must return positive numbers") panic("ebiten: Layout must return positive numbers")
@ -74,7 +74,7 @@ func (c *uiContext) UpdateOffscreen(outsideWidth, outsideHeight float64, deviceS
return ow, oh return ow, oh
} }
func (c *uiContext) setScreenClearedEveryFrame(cleared bool) { func (c *gameForUI) setScreenClearedEveryFrame(cleared bool) {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
@ -83,11 +83,11 @@ func (c *uiContext) setScreenClearedEveryFrame(cleared bool) {
} }
} }
func (c *uiContext) UpdateGame() error { func (c *gameForUI) Update() error {
return c.game.Update() return c.game.Update()
} }
func (c *uiContext) DrawGame(screenScale float64, offsetX, offsetY float64, needsClearingScreen bool, framebufferYDirection graphicsdriver.YDirection) error { func (c *gameForUI) Draw(screenScale float64, offsetX, offsetY float64, needsClearingScreen bool, framebufferYDirection graphicsdriver.YDirection) error {
// Even though updateCount == 0, the offscreen is cleared and Draw is called. // 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 // 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. // users might want to process something at Draw with the time intervals of FPS.

View File

@ -29,29 +29,29 @@ import (
const DefaultTPS = 60 const DefaultTPS = 60
type Context interface { type Game interface {
UpdateOffscreen(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int) Layout(outsideWidth, outsideHeight float64, deviceScaleFactor float64) (int, int)
UpdateGame() error Update() error
DrawGame(screenScale float64, offsetX, offsetY float64, needsClearingScreen bool, framebufferYDirection graphicsdriver.YDirection) error Draw(screenScale float64, offsetX, offsetY float64, needsClearingScreen bool, framebufferYDirection graphicsdriver.YDirection) error
} }
type contextImpl struct { type contextImpl struct {
context Context game Game
updateCalled bool updateCalled bool
// The following members must be protected by the mutex m. // The following members must be protected by the mutex m.
outsideWidth float64 outsideWidth float64
outsideHeight float64 outsideHeight float64
offscreenWidth int screenWidth int
offscreenHeight int screenHeight int
m sync.Mutex m sync.Mutex
} }
func newContextImpl(context Context) *contextImpl { func newContextImpl(game Game) *contextImpl {
return &contextImpl{ return &contextImpl{
context: context, game: game,
} }
} }
@ -70,7 +70,7 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
} }
// ForceUpdate can be invoked even if the context is not initialized yet (#1591). // ForceUpdate can be invoked even if the context is not initialized yet (#1591).
if w, h := c.updateOffscreenSize(deviceScaleFactor); w == 0 || h == 0 { if w, h := c.layoutGame(deviceScaleFactor); w == 0 || h == 0 {
return nil return nil
} }
@ -92,7 +92,7 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
if err := hooks.RunBeforeUpdateHooks(); err != nil { if err := hooks.RunBeforeUpdateHooks(); err != nil {
return err return err
} }
if err := c.context.UpdateGame(); err != nil { if err := c.game.Update(); err != nil {
return err return err
} }
Get().resetForTick() Get().resetForTick()
@ -100,7 +100,7 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
// Draw the game. // Draw the game.
screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor) screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor)
if err := c.context.DrawGame(screenScale, offsetX, offsetY, graphics().NeedsClearingScreen(), graphics().FramebufferYDirection()); err != nil { if err := c.game.Draw(screenScale, offsetX, offsetY, graphics().NeedsClearingScreen(), graphics().FramebufferYDirection()); err != nil {
return err return err
} }
@ -114,13 +114,13 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
}) })
} }
func (c *contextImpl) updateOffscreenSize(deviceScaleFactor float64) (int, int) { func (c *contextImpl) layoutGame(deviceScaleFactor float64) (int, int) {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
w, h := c.context.UpdateOffscreen(c.outsideWidth, c.outsideHeight, deviceScaleFactor) w, h := c.game.Layout(c.outsideWidth, c.outsideHeight, deviceScaleFactor)
c.offscreenWidth = w c.screenWidth = w
c.offscreenHeight = h c.screenHeight = h
return w, h return w, h
} }
@ -139,7 +139,7 @@ func (c *contextImpl) layout(outsideWidth, outsideHeight float64) {
func (c *contextImpl) adjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64) { func (c *contextImpl) adjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64) {
s, ox, oy := c.screenScaleAndOffsets(deviceScaleFactor) s, ox, oy := c.screenScaleAndOffsets(deviceScaleFactor)
// The scale 0 indicates that the offscreen is not initialized yet. // The scale 0 indicates that the screen is not initialized yet.
// As any cursor values don't make sense, just return NaN. // As any cursor values don't make sense, just return NaN.
if s == 0 { if s == 0 {
return math.NaN(), math.NaN() return math.NaN(), math.NaN()
@ -151,15 +151,15 @@ func (c *contextImpl) screenScaleAndOffsets(deviceScaleFactor float64) (float64,
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
if c.offscreenWidth == 0 || c.offscreenHeight == 0 { if c.screenWidth == 0 || c.screenHeight == 0 {
return 0, 0, 0 return 0, 0, 0
} }
scaleX := c.outsideWidth / float64(c.offscreenWidth) * deviceScaleFactor scaleX := c.outsideWidth / float64(c.screenWidth) * deviceScaleFactor
scaleY := c.outsideHeight / float64(c.offscreenHeight) * deviceScaleFactor scaleY := c.outsideHeight / float64(c.screenHeight) * deviceScaleFactor
scale := math.Min(scaleX, scaleY) scale := math.Min(scaleX, scaleY)
width := float64(c.offscreenWidth) * scale width := float64(c.screenWidth) * scale
height := float64(c.offscreenHeight) * scale height := float64(c.screenHeight) * scale
x := (c.outsideWidth*deviceScaleFactor - width) / 2 x := (c.outsideWidth*deviceScaleFactor - width) / 2
y := (c.outsideHeight*deviceScaleFactor - height) / 2 y := (c.outsideHeight*deviceScaleFactor - height) / 2
return scale, x, y return scale, x, y

View File

@ -22,8 +22,8 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/thread" "github.com/hajimehoshi/ebiten/v2/internal/thread"
) )
func (u *UserInterface) Run(context Context) error { func (u *UserInterface) Run(game Game) error {
u.context = newContextImpl(context) u.context = newContextImpl(game)
// Initialize the main thread first so the thread is available at u.run (#809). // Initialize the main thread first so the thread is available at u.run (#809).
u.t = thread.NewOSThread() u.t = thread.NewOSThread()

View File

@ -22,8 +22,8 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/thread" "github.com/hajimehoshi/ebiten/v2/internal/thread"
) )
func (u *UserInterface) Run(context Context) error { func (u *UserInterface) Run(game Game) error {
u.context = newContextImpl(context) u.context = newContextImpl(game)
// Initialize the main thread first so the thread is available at u.run (#809). // Initialize the main thread first so the thread is available at u.run (#809).
u.t = thread.NewNoopThread() u.t = thread.NewNoopThread()

View File

@ -40,8 +40,8 @@ func Get() *UserInterface {
return &theUserInterface return &theUserInterface
} }
func (u *UserInterface) Run(context Context) error { func (u *UserInterface) Run(game Game) error {
u.context = newContextImpl(context) u.context = newContextImpl(game)
cbackend.InitializeGame() cbackend.InitializeGame()
for { for {
w, h := cbackend.ScreenSize() w, h := cbackend.ScreenSize()
@ -58,7 +58,7 @@ func (u *UserInterface) Run(context Context) error {
} }
} }
func (*UserInterface) RunWithoutMainLoop(context Context) { func (*UserInterface) RunWithoutMainLoop(game Game) {
panic("ui: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }

View File

@ -642,7 +642,7 @@ func init() {
runtime.LockOSThread() runtime.LockOSThread()
} }
func (u *UserInterface) RunWithoutMainLoop(context Context) { func (u *UserInterface) RunWithoutMainLoop(game Game) {
panic("ui: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }

View File

@ -314,8 +314,8 @@ func (u *UserInterface) needsUpdate() bool {
return false return false
} }
func (u *UserInterface) loop(context Context) <-chan error { func (u *UserInterface) loop(game Game) <-chan error {
u.context = newContextImpl(context) u.context = newContextImpl(game)
errCh := make(chan error, 1) errCh := make(chan error, 1)
reqStopAudioCh := make(chan struct{}) reqStopAudioCh := make(chan struct{})
@ -587,7 +587,7 @@ func (u *UserInterface) forceUpdateOnMinimumFPSMode() {
u.updateImpl(true) u.updateImpl(true)
} }
func (u *UserInterface) Run(context Context) error { func (u *UserInterface) Run(game Game) error {
if u.initFocused && window.Truthy() { if u.initFocused && window.Truthy() {
// Do not focus the canvas when the current document is in an iframe. // Do not focus the canvas when the current document is in an iframe.
// Otherwise, the parent page tries to focus the iframe on every loading, which is annoying (#1373). // Otherwise, the parent page tries to focus the iframe on every loading, which is annoying (#1373).
@ -597,10 +597,10 @@ func (u *UserInterface) Run(context Context) error {
} }
} }
u.running = true u.running = true
return <-u.loop(context) return <-u.loop(game)
} }
func (u *UserInterface) RunWithoutMainLoop(context Context) { func (u *UserInterface) RunWithoutMainLoop(game Game) {
panic("ui: RunWithoutMainLoop is not implemented") panic("ui: RunWithoutMainLoop is not implemented")
} }

View File

@ -238,10 +238,10 @@ func (u *UserInterface) SetForeground(foreground bool) error {
} }
} }
func (u *UserInterface) Run(context Context) error { func (u *UserInterface) Run(game Game) error {
u.setGBuildSizeCh = make(chan struct{}) u.setGBuildSizeCh = make(chan struct{})
go func() { go func() {
if err := u.run(context, true); err != nil { if err := u.run(game, true); err != nil {
// As mobile apps never ends, Loop can't return. Just panic here. // As mobile apps never ends, Loop can't return. Just panic here.
panic(err) panic(err)
} }
@ -250,15 +250,15 @@ func (u *UserInterface) Run(context Context) error {
return nil return nil
} }
func (u *UserInterface) RunWithoutMainLoop(context Context) { func (u *UserInterface) RunWithoutMainLoop(game Game) {
go func() { go func() {
if err := u.run(context, false); err != nil { if err := u.run(game, false); err != nil {
u.errCh <- err u.errCh <- err
} }
}() }()
} }
func (u *UserInterface) run(context Context, mainloop bool) (err error) { func (u *UserInterface) run(game Game, mainloop bool) (err error) {
// Convert the panic to a regular error so that Java/Objective-C layer can treat this easily e.g., for // Convert the panic to a regular error so that Java/Objective-C layer can treat this easily e.g., for
// Crashlytics. A panic is treated as SIGABRT, and there is no way to handle this on Java/Objective-C layer // Crashlytics. A panic is treated as SIGABRT, and there is no way to handle this on Java/Objective-C layer
// unfortunately. // unfortunately.
@ -273,7 +273,7 @@ func (u *UserInterface) run(context Context, mainloop bool) (err error) {
u.sizeChanged = true u.sizeChanged = true
u.m.Unlock() u.m.Unlock()
u.context = newContextImpl(context) u.context = newContextImpl(game)
if mainloop { if mainloop {
// When mainloop is true, gomobile-build is used. In this case, GL functions must be called via // When mainloop is true, gomobile-build is used. In this case, GL functions must be called via

6
run.go
View File

@ -91,7 +91,7 @@ func SetScreenClearedEveryFrame(cleared bool) {
v = 1 v = 1
} }
atomic.StoreInt32(&isScreenClearedEveryFrame, v) atomic.StoreInt32(&isScreenClearedEveryFrame, v)
theUIContext.setScreenClearedEveryFrame(cleared) theGameForUI.setScreenClearedEveryFrame(cleared)
} }
// IsScreenClearedEveryFrame returns true if the frame isn't cleared at the beginning. // IsScreenClearedEveryFrame returns true if the frame isn't cleared at the beginning.
@ -156,10 +156,10 @@ func RunGame(game Game) error {
defer atomic.StoreInt32(&isRunGameEnded_, 1) defer atomic.StoreInt32(&isRunGameEnded_, 1)
initializeWindowPositionIfNeeded(WindowSize()) initializeWindowPositionIfNeeded(WindowSize())
theUIContext.set(&imageDumperGame{ theGameForUI.set(&imageDumperGame{
game: game, game: game,
}) })
if err := ui.Get().Run(theUIContext); err != nil { if err := ui.Get().Run(theGameForUI); err != nil {
if err == ui.RegularTermination { if err == ui.RegularTermination {
return nil return nil
} }

View File

@ -29,6 +29,6 @@ import (
// //
// TODO: Remove this. In order to remove this, the uiContext should be in another package. // TODO: Remove this. In order to remove this, the uiContext should be in another package.
func RunGameWithoutMainLoop(game Game) { func RunGameWithoutMainLoop(game Game) {
theUIContext.set(game) theGameForUI.set(game)
ui.Get().RunWithoutMainLoop(theUIContext) ui.Get().RunWithoutMainLoop(theGameForUI)
} }