mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 11:48:55 +01:00
parent
5f81065d78
commit
9400efa9a5
@ -20,6 +20,7 @@ type Thread interface {
|
|||||||
Call(f func() error) error
|
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) {
|
func SetMainThread(thread Thread) {
|
||||||
theThread = thread
|
theThread = thread
|
||||||
}
|
}
|
||||||
|
@ -59,3 +59,32 @@ func (u *UserInterface) Run(uicontext driver.UIContext) error {
|
|||||||
u.setRunning(false)
|
u.setRunning(false)
|
||||||
return <-ch
|
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)
|
u.setRunning(false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserInterface) runOnAnotherThreadFromMainThread(f func() error) error {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
@ -50,6 +50,9 @@ type UserInterface struct {
|
|||||||
runnableOnUnfocused bool
|
runnableOnUnfocused bool
|
||||||
vsync bool
|
vsync bool
|
||||||
|
|
||||||
|
// err must be accessed from the main thread.
|
||||||
|
err error
|
||||||
|
|
||||||
lastDeviceScaleFactor float64
|
lastDeviceScaleFactor float64
|
||||||
|
|
||||||
initMonitor *glfw.Monitor
|
initMonitor *glfw.Monitor
|
||||||
@ -73,9 +76,6 @@ type UserInterface struct {
|
|||||||
|
|
||||||
vsyncInited bool
|
vsyncInited bool
|
||||||
|
|
||||||
reqWidth int
|
|
||||||
reqHeight int
|
|
||||||
|
|
||||||
input Input
|
input Input
|
||||||
iwindow window
|
iwindow window
|
||||||
|
|
||||||
@ -628,8 +628,35 @@ func (u *UserInterface) createWindow() error {
|
|||||||
if u.isFullscreen() {
|
if u.isFullscreen() {
|
||||||
return
|
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
|
return nil
|
||||||
@ -754,6 +781,10 @@ func (u *UserInterface) updateSize() (float64, float64, bool) {
|
|||||||
|
|
||||||
// update must be called from the main thread.
|
// update must be called from the main thread.
|
||||||
func (u *UserInterface) update() (float64, float64, bool, error) {
|
func (u *UserInterface) update() (float64, float64, bool, error) {
|
||||||
|
if u.err != nil {
|
||||||
|
return 0, 0, false, u.err
|
||||||
|
}
|
||||||
|
|
||||||
if u.window.ShouldClose() {
|
if u.window.ShouldClose() {
|
||||||
return 0, 0, false, driver.RegularTermination
|
return 0, 0, false, driver.RegularTermination
|
||||||
}
|
}
|
||||||
@ -772,13 +803,6 @@ func (u *UserInterface) update() (float64, float64, bool, error) {
|
|||||||
u.vsyncInited = true
|
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()
|
outsideWidth, outsideHeight, outsideSizeChanged := u.updateSize()
|
||||||
|
|
||||||
// TODO: Updating the input can be skipped when clock.Update returns 0 (#1367).
|
// TODO: Updating the input can be skipped when clock.Update returns 0 (#1367).
|
||||||
|
Loading…
Reference in New Issue
Block a user