mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/uidriver/glfw: Bug fix: Avoid registring C callbacks too often
Instead of registring/unregistering callbacks, use a boolean flag. Closes #1588
This commit is contained in:
parent
c88ee0d0ad
commit
7e61189c3d
@ -72,6 +72,9 @@ type UserInterface struct {
|
|||||||
iconImages []image.Image
|
iconImages []image.Image
|
||||||
cursorShape driver.CursorShape
|
cursorShape driver.CursorShape
|
||||||
|
|
||||||
|
// setSizeCallbackEnabled must be accessed from the main thread.
|
||||||
|
setSizeCallbackEnabled bool
|
||||||
|
|
||||||
// err must be accessed from the main thread.
|
// err must be accessed from the main thread.
|
||||||
err error
|
err error
|
||||||
|
|
||||||
@ -705,14 +708,14 @@ func (u *UserInterface) createWindow() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// unregisterWindowSetSizeCallback must be called from the main thread.
|
|
||||||
func (u *UserInterface) unregisterWindowSetSizeCallback() bool {
|
|
||||||
return u.window.SetSizeCallback(nil) != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// registerWindowSetSizeCallback must be called from the main thread.
|
// registerWindowSetSizeCallback must be called from the main thread.
|
||||||
func (u *UserInterface) registerWindowSetSizeCallback() {
|
func (u *UserInterface) registerWindowSetSizeCallback() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
u.window.SetSizeCallback(func(_ *glfw.Window, width, height int) {
|
u.window.SetSizeCallback(func(_ *glfw.Window, width, height int) {
|
||||||
|
if !u.setSizeCallbackEnabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if u.window.GetAttrib(glfw.Resizable) == glfw.False {
|
if u.window.GetAttrib(glfw.Resizable) == glfw.False {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1100,11 +1103,14 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
|
|||||||
// swap buffers here before SetSize is called.
|
// swap buffers here before SetSize is called.
|
||||||
u.swapBuffers()
|
u.swapBuffers()
|
||||||
|
|
||||||
// Do not fire the callback of SetSize. This callback can be invoked by SetMonitor or SetSize.
|
// Disable the callback of SetSize. This callback can be invoked by SetMonitor or SetSize.
|
||||||
// ForceUpdate is called from the callback.
|
// ForceUpdate is called from the callback.
|
||||||
// While setWindowSize can be called from Update, calling ForceUpdate inside Update is illegal (#1505).
|
// While setWindowSize can be called from Update, calling ForceUpdate inside Update is illegal (#1505).
|
||||||
if u.unregisterWindowSetSizeCallback() {
|
if u.setSizeCallbackEnabled {
|
||||||
defer u.registerWindowSetSizeCallback()
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var windowRecreated bool
|
var windowRecreated bool
|
||||||
@ -1330,20 +1336,26 @@ func (u *UserInterface) Window() driver.Window {
|
|||||||
|
|
||||||
func (u *UserInterface) maximize() {
|
func (u *UserInterface) maximize() {
|
||||||
// Maximize invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
// Maximize invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
||||||
if u.unregisterWindowSetSizeCallback() {
|
if u.setSizeCallbackEnabled {
|
||||||
defer u.registerWindowSetSizeCallback()
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
u.window.Maximize()
|
u.window.Maximize()
|
||||||
|
|
||||||
// Call setWindowSize explicitly in order to update the rendering since the callback is unregistered now.
|
// Call setWindowSize explicitly in order to update the rendering since the callback is disabled now.
|
||||||
w, h := u.window.GetSize()
|
w, h := u.window.GetSize()
|
||||||
u.setWindowSize(w, h, u.isFullscreen())
|
u.setWindowSize(w, h, u.isFullscreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) iconify() {
|
func (u *UserInterface) iconify() {
|
||||||
// Iconify invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
// Iconify invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
||||||
if u.unregisterWindowSetSizeCallback() {
|
if u.setSizeCallbackEnabled {
|
||||||
defer u.registerWindowSetSizeCallback()
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
u.window.Iconify()
|
u.window.Iconify()
|
||||||
|
|
||||||
@ -1353,12 +1365,15 @@ func (u *UserInterface) iconify() {
|
|||||||
|
|
||||||
func (u *UserInterface) restore() {
|
func (u *UserInterface) restore() {
|
||||||
// Restore invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
// Restore invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
||||||
if u.unregisterWindowSetSizeCallback() {
|
if u.setSizeCallbackEnabled {
|
||||||
defer u.registerWindowSetSizeCallback()
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
u.window.Restore()
|
u.window.Restore()
|
||||||
|
|
||||||
// Call setWindowSize explicitly in order to update the rendering since the callback is unregistered now.
|
// Call setWindowSize explicitly in order to update the rendering since the callback is disabled now.
|
||||||
w, h := u.window.GetSize()
|
w, h := u.window.GetSize()
|
||||||
u.setWindowSize(w, h, u.isFullscreen())
|
u.setWindowSize(w, h, u.isFullscreen())
|
||||||
}
|
}
|
||||||
@ -1366,8 +1381,11 @@ func (u *UserInterface) restore() {
|
|||||||
func (u *UserInterface) setDecorated(decorated bool) {
|
func (u *UserInterface) setDecorated(decorated bool) {
|
||||||
// SetAttrib with glfw.Decorated invokes the SetSize callback but the callback must not be called in the game's Update (#1586).
|
// SetAttrib with glfw.Decorated invokes the SetSize callback but the callback must not be called in the game's Update (#1586).
|
||||||
// SetSize callback is invoked in the limited situations like just after restoring from the fullscreen mode.
|
// SetSize callback is invoked in the limited situations like just after restoring from the fullscreen mode.
|
||||||
if u.unregisterWindowSetSizeCallback() {
|
if u.setSizeCallbackEnabled {
|
||||||
defer u.registerWindowSetSizeCallback()
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
v := glfw.False
|
v := glfw.False
|
||||||
if decorated {
|
if decorated {
|
||||||
|
Loading…
Reference in New Issue
Block a user