driver: Simplify UIContext.Update

This commit is contained in:
Hajime Hoshi 2020-04-03 00:06:42 +09:00
parent 218281ce6f
commit 8777140e91
9 changed files with 50 additions and 39 deletions

View File

@ -25,7 +25,6 @@ type Input interface {
IsGamepadButtonPressed(id int, button GamepadButton) bool
IsKeyPressed(key Key) bool
IsMouseButtonPressed(button MouseButton) bool
ResetForFrame()
RuneBuffer() []rune
TouchIDs() []int
TouchPosition(id int) (x, y int)

View File

@ -20,7 +20,7 @@ import (
)
type UIContext interface {
Update(afterFrameUpdate func()) error
Update() error
Draw() error
Layout(outsideWidth, outsideHeight float64)
AdjustPosition(x, y float64) (float64, float64)
@ -38,6 +38,7 @@ type UI interface {
DeviceScaleFactor() float64
IsFocused() bool
ScreenSizeInFullscreen() (int, int)
ResetForFrame()
CursorMode() CursorMode
SetCursorMode(mode CursorMode)

View File

@ -228,7 +228,7 @@ func (i *Input) RuneBuffer() []rune {
return r
}
func (i *Input) ResetForFrame() {
func (i *Input) resetForFrame() {
if !i.ui.isRunning() {
return
}

View File

@ -37,8 +37,9 @@ import (
)
type UserInterface struct {
title string
window *glfw.Window
context driver.UIContext
title string
window *glfw.Window
// windowWidth and windowHeight represents a window size.
// The unit is device-dependent pixels.
@ -552,6 +553,8 @@ func init() {
}
func (u *UserInterface) Run(uicontext driver.UIContext) error {
u.context = uicontext
// Initialize the main thread first so the thread is available at u.run (#809).
u.t = thread.New()
u.Graphics().SetThread(u.t)
@ -562,7 +565,7 @@ func (u *UserInterface) Run(uicontext driver.UIContext) error {
go func() {
defer cancel()
defer close(ch)
if err := u.run(uicontext); err != nil {
if err := u.run(); err != nil {
ch <- err
}
}()
@ -626,7 +629,7 @@ func (u *UserInterface) createWindow() error {
return nil
}
func (u *UserInterface) run(context driver.UIContext) error {
func (u *UserInterface) run() error {
if err := u.t.Call(func() error {
// The window is created at initialize().
u.window.Destroy()
@ -725,10 +728,10 @@ func (u *UserInterface) run(context driver.UIContext) error {
if g, ok := u.Graphics().(interface{ SetWindow(unsafe.Pointer) }); ok {
g.SetWindow(w)
}
return u.loop(context)
return u.loop()
}
func (u *UserInterface) updateSize(context driver.UIContext) {
func (u *UserInterface) updateSize() {
var w, h int
_ = u.t.Call(func() error {
w, h = u.windowWidth, u.windowHeight
@ -761,11 +764,11 @@ func (u *UserInterface) updateSize(context driver.UIContext) {
h = u.toDeviceIndependentPixel(float64(wh))
return nil
})
context.Layout(w, h)
u.context.Layout(w, h)
}
}
func (u *UserInterface) update(context driver.UIContext) error {
func (u *UserInterface) update() error {
shouldClose := false
_ = u.t.Call(func() error {
shouldClose = u.window.ShouldClose()
@ -786,13 +789,13 @@ func (u *UserInterface) update(context driver.UIContext) error {
}
// This call is needed for initialization.
u.updateSize(context)
u.updateSize()
_ = u.t.Call(func() error {
glfw.PollEvents()
return nil
})
u.input.update(u.window, context)
u.input.update(u.window, u.context)
_ = u.t.Call(func() error {
defer hooks.ResumeAudio()
@ -807,13 +810,10 @@ func (u *UserInterface) update(context driver.UIContext) error {
}
return nil
})
if err := context.Update(func() {
// The offscreens must be updated every frame (#490).
u.updateSize(context)
}); err != nil {
if err := u.context.Update(); err != nil {
return err
}
if err := context.Draw(); err != nil {
if err := u.context.Draw(); err != nil {
return err
}
@ -834,7 +834,7 @@ func (u *UserInterface) update(context driver.UIContext) error {
return nil
}
func (u *UserInterface) loop(context driver.UIContext) error {
func (u *UserInterface) loop() error {
defer func() {
_ = u.t.Call(func() error {
glfw.Terminate()
@ -856,7 +856,7 @@ func (u *UserInterface) loop(context driver.UIContext) error {
if unfocused {
t1 = time.Now()
}
if err := u.update(context); err != nil {
if err := u.update(); err != nil {
return err
}
@ -1065,6 +1065,12 @@ func (u *UserInterface) IsScreenTransparent() bool {
return val
}
func (u *UserInterface) ResetForFrame() {
// The offscreens must be updated every frame (#490).
u.updateSize()
u.input.resetForFrame()
}
func (u *UserInterface) Input() driver.Input {
return &u.input
}

View File

@ -146,7 +146,7 @@ func (i *Input) RuneBuffer() []rune {
return i.runeBuffer
}
func (i *Input) ResetForFrame() {
func (i *Input) resetForFrame() {
i.runeBuffer = nil
i.wheelX = 0
i.wheelY = 0

View File

@ -167,9 +167,7 @@ func (u *UserInterface) update() error {
u.input.UpdateGamepads()
u.updateSize()
if err := u.context.Update(func() {
u.updateSize()
}); err != nil {
if err := u.context.Update(); err != nil {
return err
}
if err := u.context.Draw(); err != nil {
@ -459,6 +457,11 @@ func (u *UserInterface) IsScreenTransparent() bool {
return bodyStyle.Get("backgroundColor").String() == "transparent"
}
func (u *UserInterface) ResetForFrame() {
u.updateSize()
u.input.resetForFrame()
}
func (u *UserInterface) Input() driver.Input {
return &u.input
}

View File

@ -210,6 +210,6 @@ func (i *Input) update(keys map[driver.Key]struct{}, runes []rune, touches []*To
copy(i.gamepads, gamepads)
}
func (i *Input) ResetForFrame() {
func (i *Input) resetForFrame() {
i.runes = nil
}

View File

@ -302,15 +302,15 @@ func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error)
}
// Force to set the screen size
u.updateSize(context)
u.updateSize()
for {
if err := u.update(context); err != nil {
if err := u.update(); err != nil {
return err
}
}
}
func (u *UserInterface) updateSize(context driver.UIContext) {
func (u *UserInterface) updateSize() {
var outsideWidth, outsideHeight float64
u.m.Lock()
@ -330,22 +330,20 @@ func (u *UserInterface) updateSize(context driver.UIContext) {
u.m.Unlock()
if sizeChanged {
context.Layout(outsideWidth, outsideHeight)
u.context.Layout(outsideWidth, outsideHeight)
}
}
func (u *UserInterface) update(context driver.UIContext) error {
func (u *UserInterface) update() error {
<-renderCh
defer func() {
renderEndCh <- struct{}{}
}()
if err := context.Update(func() {
u.updateSize(context)
}); err != nil {
if err := u.context.Update(); err != nil {
return err
}
if err := context.Draw(); err != nil {
if err := u.context.Draw(); err != nil {
return err
}
return nil
@ -436,6 +434,11 @@ func (u *UserInterface) IsScreenTransparent() bool {
return false
}
func (u *UserInterface) ResetForFrame() {
u.updateSize()
u.input.resetForFrame()
}
func (u *UserInterface) Input() driver.Input {
return &u.input
}

View File

@ -227,7 +227,7 @@ func (c *uiContext) offsets() (float64, float64) {
return (c.outsideWidth*d - width) / 2, (c.outsideHeight*d - height) / 2
}
func (c *uiContext) Update(afterFrameUpdate func()) error {
func (c *uiContext) Update() error {
// TODO: If updateCount is 0 and vsync is disabled, swapping buffers can be skipped.
if err, ok := c.err.Load().(error); ok && err != nil {
@ -236,7 +236,7 @@ func (c *uiContext) Update(afterFrameUpdate func()) error {
if err := buffered.BeginFrame(); err != nil {
return err
}
if err := c.update(afterFrameUpdate); err != nil {
if err := c.update(); err != nil {
return err
}
if err := buffered.EndFrame(); err != nil {
@ -259,7 +259,7 @@ func (c *uiContext) Draw() error {
return nil
}
func (c *uiContext) update(afterFrameUpdate func()) error {
func (c *uiContext) update() error {
_, hasDraw := c.game.(interface{ Draw(*Image) })
updateCount := clock.Update(MaxTPS())
@ -285,8 +285,7 @@ func (c *uiContext) update(afterFrameUpdate func()) error {
if err := c.game.Update(c.offscreen); err != nil {
return err
}
uiDriver().Input().ResetForFrame()
afterFrameUpdate()
uiDriver().ResetForFrame()
}
return nil
}