internal/ui: refactoring: remove (*contextImpl).layout

This commit is contained in:
Hajime Hoshi 2022-02-14 02:48:28 +09:00
parent cffa123405
commit 871121abe3
5 changed files with 39 additions and 44 deletions

View File

@ -55,20 +55,31 @@ func newContextImpl(game Game) *contextImpl {
} }
} }
func (c *contextImpl) updateFrame(deviceScaleFactor float64) error { func (c *contextImpl) updateFrame(outsideWidth, outsideHeight float64, deviceScaleFactor float64) error {
// TODO: If updateCount is 0 and vsync is disabled, swapping buffers can be skipped. // TODO: If updateCount is 0 and vsync is disabled, swapping buffers can be skipped.
return c.updateFrameImpl(clock.Update(theGlobalState.maxTPS()), deviceScaleFactor) return c.updateFrameImpl(clock.Update(theGlobalState.maxTPS()), outsideWidth, outsideHeight, deviceScaleFactor)
} }
func (c *contextImpl) forceUpdateFrame(deviceScaleFactor float64) error { func (c *contextImpl) forceUpdateFrame(outsideWidth, outsideHeight float64, deviceScaleFactor float64) error {
return c.updateFrameImpl(1, deviceScaleFactor) return c.updateFrameImpl(1, outsideWidth, outsideHeight, deviceScaleFactor)
} }
func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64) error { func (c *contextImpl) updateFrameImpl(updateCount int, outsideWidth, outsideHeight float64, deviceScaleFactor float64) error {
if err := theGlobalState.err(); err != nil { if err := theGlobalState.err(); err != nil {
return err return err
} }
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
// Just ignore such cases. Otherwise, creating a zero-sized framebuffer causes a panic.
if outsideWidth == 0 || outsideHeight == 0 {
return nil
}
c.m.Lock()
c.outsideWidth = outsideWidth
c.outsideHeight = outsideHeight
c.m.Unlock()
// 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.layoutGame(deviceScaleFactor); w == 0 || h == 0 { if w, h := c.layoutGame(deviceScaleFactor); w == 0 || h == 0 {
return nil return nil
@ -124,19 +135,6 @@ func (c *contextImpl) layoutGame(deviceScaleFactor float64) (int, int) {
return w, h return w, h
} }
func (c *contextImpl) layout(outsideWidth, outsideHeight float64) {
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
// Just ignore such cases. Otherwise, creating a zero-sized framebuffer causes a panic.
if outsideWidth == 0 || outsideHeight == 0 {
return
}
c.m.Lock()
defer c.m.Unlock()
c.outsideWidth = outsideWidth
c.outsideHeight = outsideHeight
}
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 screen is not initialized yet. // The scale 0 indicates that the screen is not initialized yet.

View File

@ -44,13 +44,11 @@ func (u *UserInterface) Run(game Game) error {
u.context = newContextImpl(game) u.context = newContextImpl(game)
cbackend.InitializeGame() cbackend.InitializeGame()
for { for {
w, h := cbackend.ScreenSize()
u.context.layout(float64(w), float64(h))
cbackend.BeginFrame() cbackend.BeginFrame()
u.input.update(u.context) u.input.update(u.context)
if err := u.context.updateFrame(deviceScaleFactor); err != nil { w, h := cbackend.ScreenSize()
if err := u.context.updateFrame(float64(w), float64(h), deviceScaleFactor); err != nil {
return err return err
} }

View File

@ -715,8 +715,7 @@ func (u *UserInterface) registerWindowSetSizeCallback() {
// In order to call it safely, use runOnAnotherThreadFromMainThread. // In order to call it safely, use runOnAnotherThreadFromMainThread.
var err error var err error
u.runOnAnotherThreadFromMainThread(func() { u.runOnAnotherThreadFromMainThread(func() {
u.context.layout(outsideWidth, outsideHeight) err = u.context.forceUpdateFrame(outsideWidth, outsideHeight, deviceScaleFactor)
err = u.context.forceUpdateFrame(deviceScaleFactor)
}) })
if err != nil { if err != nil {
u.err = err u.err = err
@ -1025,9 +1024,8 @@ func (u *UserInterface) loop() error {
}); err != nil { }); err != nil {
return err return err
} }
u.context.layout(outsideWidth, outsideHeight)
if err := u.context.updateFrame(deviceScaleFactor); err != nil { if err := u.context.updateFrame(outsideWidth, outsideHeight, deviceScaleFactor); err != nil {
return err return err
} }

View File

@ -219,26 +219,20 @@ func (u *UserInterface) DeviceScaleFactor() float64 {
return devicescale.GetAt(0, 0) return devicescale.GetAt(0, 0)
} }
func (u *UserInterface) updateSize() { func (u *UserInterface) outsideSize() (float64, float64) {
a := u.DeviceScaleFactor()
if u.lastDeviceScaleFactor != a {
u.updateScreenSize()
}
u.lastDeviceScaleFactor = a
switch { switch {
case document.Truthy(): case document.Truthy():
body := document.Get("body") body := document.Get("body")
bw := body.Get("clientWidth").Float() bw := body.Get("clientWidth").Float()
bh := body.Get("clientHeight").Float() bh := body.Get("clientHeight").Float()
u.context.layout(bw, bh) return bw, bh
case go2cpp.Truthy(): case go2cpp.Truthy():
w := go2cpp.Get("screenWidth").Float() w := go2cpp.Get("screenWidth").Float()
h := go2cpp.Get("screenHeight").Float() h := go2cpp.Get("screenHeight").Float()
u.context.layout(w, h) return w, h
default: default:
// Node.js // Node.js
u.context.layout(640, 480) return 640, 480
} }
} }
@ -281,13 +275,20 @@ func (u *UserInterface) updateImpl(force bool) error {
gamepad.Update() gamepad.Update()
u.input.updateForGo2Cpp() u.input.updateForGo2Cpp()
u.updateSize()
a := u.DeviceScaleFactor()
if u.lastDeviceScaleFactor != a {
u.updateScreenSize()
}
u.lastDeviceScaleFactor = a
w, h := u.outsideSize()
if force { if force {
if err := u.context.forceUpdateFrame(u.DeviceScaleFactor()); err != nil { if err := u.context.forceUpdateFrame(w, h, u.DeviceScaleFactor()); err != nil {
return err return err
} }
} else { } else {
if err := u.context.updateFrame(u.DeviceScaleFactor()); err != nil { if err := u.context.updateFrame(w, h, u.DeviceScaleFactor()); err != nil {
return err return err
} }
} }

View File

@ -295,8 +295,8 @@ func (u *UserInterface) run(game Game, mainloop bool) (err error) {
} }
} }
// layoutIfNeeded must be called on the same goroutine as update(). // outsideSize must be called on the same goroutine as update().
func (u *UserInterface) layoutIfNeeded() { func (u *UserInterface) outsideSize() (float64, float64) {
var outsideWidth, outsideHeight float64 var outsideWidth, outsideHeight float64
u.m.RLock() u.m.RLock()
@ -311,7 +311,7 @@ func (u *UserInterface) layoutIfNeeded() {
} }
u.m.RUnlock() u.m.RUnlock()
u.context.layout(outsideWidth, outsideHeight) return outsideWidth, outsideHeight
} }
func (u *UserInterface) update() error { func (u *UserInterface) update() error {
@ -320,8 +320,8 @@ func (u *UserInterface) update() error {
renderEndCh <- struct{}{} renderEndCh <- struct{}{}
}() }()
u.layoutIfNeeded() w, h := u.outsideSize()
if err := u.context.updateFrame(deviceScale()); err != nil { if err := u.context.updateFrame(w, h, deviceScale()); err != nil {
return err return err
} }
return nil return nil