mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
parent
5f81065d78
commit
9400efa9a5
@ -20,6 +20,7 @@ type Thread interface {
|
||||
Call(f func() error) error
|
||||
}
|
||||
|
||||
// SetMainThread must be called from the main thread (i.e, the goroutine where the thread is created).
|
||||
func SetMainThread(thread Thread) {
|
||||
theThread = thread
|
||||
}
|
||||
|
@ -59,3 +59,32 @@ func (u *UserInterface) Run(uicontext driver.UIContext) error {
|
||||
u.setRunning(false)
|
||||
return <-ch
|
||||
}
|
||||
|
||||
// runOnAnotherThreadFromMainThread is called from the main thread, and calls f on a new goroutine (thread).
|
||||
// runOnAnotherThreadFromMainThread creates a new nested main thread and runs the run loop.
|
||||
// u.t is updated to the new thread until runOnAnotherThreadFromMainThread is called.
|
||||
//
|
||||
// Inside f, another functions that must be called from the main thread can be called safely.
|
||||
func (u *UserInterface) runOnAnotherThreadFromMainThread(f func() error) error {
|
||||
// As this function is called from the main thread, u.t should never be accessed and can be updated here.
|
||||
t := u.t
|
||||
defer func() {
|
||||
u.t = t
|
||||
graphicscommand.SetMainThread(t)
|
||||
}()
|
||||
|
||||
u.t = thread.NewOSThread()
|
||||
graphicscommand.SetMainThread(u.t)
|
||||
|
||||
var err error
|
||||
go func() {
|
||||
defer func() {
|
||||
_ = u.t.Call(func() error {
|
||||
return thread.BreakLoop
|
||||
})
|
||||
}()
|
||||
err = f()
|
||||
}()
|
||||
u.t.Loop()
|
||||
return err
|
||||
}
|
||||
|
@ -45,3 +45,7 @@ func (u *UserInterface) Run(uicontext driver.UIContext) error {
|
||||
u.setRunning(false)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) runOnAnotherThreadFromMainThread(f func() error) error {
|
||||
return f()
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ type UserInterface struct {
|
||||
runnableOnUnfocused bool
|
||||
vsync bool
|
||||
|
||||
// err must be accessed from the main thread.
|
||||
err error
|
||||
|
||||
lastDeviceScaleFactor float64
|
||||
|
||||
initMonitor *glfw.Monitor
|
||||
@ -73,9 +76,6 @@ type UserInterface struct {
|
||||
|
||||
vsyncInited bool
|
||||
|
||||
reqWidth int
|
||||
reqHeight int
|
||||
|
||||
input Input
|
||||
iwindow window
|
||||
|
||||
@ -628,8 +628,35 @@ func (u *UserInterface) createWindow() error {
|
||||
if u.isFullscreen() {
|
||||
return
|
||||
}
|
||||
u.reqWidth = width
|
||||
u.reqHeight = height
|
||||
|
||||
if err := u.runOnAnotherThreadFromMainThread(func() error {
|
||||
var outsideWidth, outsideHeight float64
|
||||
var outsideSizeChanged bool
|
||||
|
||||
_ = u.t.Call(func() error {
|
||||
if width != 0 || height != 0 {
|
||||
u.setWindowSize(width, height, u.isFullscreen())
|
||||
}
|
||||
|
||||
outsideWidth, outsideHeight, outsideSizeChanged = u.updateSize()
|
||||
return nil
|
||||
})
|
||||
if outsideSizeChanged {
|
||||
u.context.Layout(outsideWidth, outsideHeight)
|
||||
}
|
||||
if err := u.context.ForceUpdate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if u.Graphics().IsGL() {
|
||||
_ = u.t.Call(func() error {
|
||||
u.swapBuffers()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
u.err = err
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
@ -754,6 +781,10 @@ func (u *UserInterface) updateSize() (float64, float64, bool) {
|
||||
|
||||
// update must be called from the main thread.
|
||||
func (u *UserInterface) update() (float64, float64, bool, error) {
|
||||
if u.err != nil {
|
||||
return 0, 0, false, u.err
|
||||
}
|
||||
|
||||
if u.window.ShouldClose() {
|
||||
return 0, 0, false, driver.RegularTermination
|
||||
}
|
||||
@ -772,13 +803,6 @@ func (u *UserInterface) update() (float64, float64, bool, error) {
|
||||
u.vsyncInited = true
|
||||
}
|
||||
|
||||
// Update the screen size when the window is resizable.
|
||||
if w, h := u.reqWidth, u.reqHeight; w != 0 || h != 0 {
|
||||
u.setWindowSize(w, h, u.isFullscreen())
|
||||
}
|
||||
u.reqWidth = 0
|
||||
u.reqHeight = 0
|
||||
|
||||
outsideWidth, outsideHeight, outsideSizeChanged := u.updateSize()
|
||||
|
||||
// TODO: Updating the input can be skipped when clock.Update returns 0 (#1367).
|
||||
|
Loading…
Reference in New Issue
Block a user