mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-02-11 02:23:15 +01:00
internal/ui: bug fix: reentering updateImpl caused double unlocking
updateImpl can be invoked in multiple ways. This should have been protected by a mutex, or this caused unexpected reentrance. Closes #2339
This commit is contained in:
parent
e808f168a1
commit
ef26267703
@ -15,6 +15,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -84,6 +85,8 @@ type userInterfaceImpl struct {
|
|||||||
|
|
||||||
context *context
|
context *context
|
||||||
input Input
|
input Input
|
||||||
|
|
||||||
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -273,6 +276,10 @@ func (u *userInterfaceImpl) update() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) updateImpl(force bool) error {
|
func (u *userInterfaceImpl) updateImpl(force bool) error {
|
||||||
|
// Guard updateImpl as this function cannot be invoked until this finishes (#2339).
|
||||||
|
u.m.Lock()
|
||||||
|
defer u.m.Unlock()
|
||||||
|
|
||||||
// context can be nil when an event is fired but the loop doesn't start yet (#1928).
|
// context can be nil when an event is fired but the loop doesn't start yet (#1928).
|
||||||
if u.context == nil {
|
if u.context == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -482,9 +489,14 @@ func init() {
|
|||||||
func setWindowEventHandlers(v js.Value) {
|
func setWindowEventHandlers(v js.Value) {
|
||||||
v.Call("addEventListener", "resize", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
v.Call("addEventListener", "resize", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
theUI.updateScreenSize()
|
theUI.updateScreenSize()
|
||||||
if err := theUI.updateImpl(true); err != nil {
|
|
||||||
panic(err)
|
// updateImpl can block. Use goroutine.
|
||||||
}
|
// See https://pkg.go.dev/syscall/js#FuncOf.
|
||||||
|
go func() {
|
||||||
|
if err := theUI.updateImpl(true); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -579,7 +591,14 @@ func (u *userInterfaceImpl) forceUpdateOnMinimumFPSMode() {
|
|||||||
if u.fpsMode != FPSModeVsyncOffMinimum {
|
if u.fpsMode != FPSModeVsyncOffMinimum {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u.updateImpl(true)
|
|
||||||
|
// updateImpl can block. Use goroutine.
|
||||||
|
// See https://pkg.go.dev/syscall/js#FuncOf.
|
||||||
|
go func() {
|
||||||
|
if err := u.updateImpl(true); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) Run(game Game) error {
|
func (u *userInterfaceImpl) Run(game Game) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user