mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/glfw: refactoring: use pointers or functions for callbacks
This commit is contained in:
parent
006b4324dc
commit
eec5ea00ec
@ -21,87 +21,60 @@ import (
|
||||
"github.com/go-gl/glfw/v3.3/glfw"
|
||||
)
|
||||
|
||||
var (
|
||||
charModsCallbacks = map[CharModsCallback]glfw.CharModsCallback{}
|
||||
closeCallbacks = map[CloseCallback]glfw.CloseCallback{}
|
||||
framebufferSizeCallbacks = map[FramebufferSizeCallback]glfw.FramebufferSizeCallback{}
|
||||
monitorCallbacks = map[MonitorCallback]glfw.MonitorCallback{}
|
||||
scrollCallbacks = map[ScrollCallback]glfw.ScrollCallback{}
|
||||
sizeCallbacks = map[SizeCallback]glfw.SizeCallback{}
|
||||
)
|
||||
|
||||
func ToCharModsCallback(cb func(window *Window, char rune, mods ModifierKey)) CharModsCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := CharModsCallback(len(charModsCallbacks) + 1)
|
||||
var gcb glfw.CharModsCallback = func(window *glfw.Window, char rune, mods glfw.ModifierKey) {
|
||||
return func(window *glfw.Window, char rune, mods glfw.ModifierKey) {
|
||||
cb(theWindows.get(window), char, ModifierKey(mods))
|
||||
}
|
||||
charModsCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
||||
func ToCloseCallback(cb func(window *Window)) CloseCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := CloseCallback(len(closeCallbacks) + 1)
|
||||
var gcb glfw.CloseCallback = func(window *glfw.Window) {
|
||||
return func(window *glfw.Window) {
|
||||
cb(theWindows.get(window))
|
||||
}
|
||||
closeCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
||||
func ToFramebufferSizeCallback(cb func(window *Window, width int, height int)) FramebufferSizeCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := FramebufferSizeCallback(len(framebufferSizeCallbacks) + 1)
|
||||
var gcb glfw.FramebufferSizeCallback = func(window *glfw.Window, width int, height int) {
|
||||
return func(window *glfw.Window, width int, height int) {
|
||||
cb(theWindows.get(window), width, height)
|
||||
}
|
||||
framebufferSizeCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
||||
func ToMonitorCallback(cb func(monitor *Monitor, event PeripheralEvent)) MonitorCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := MonitorCallback(len(monitorCallbacks) + 1)
|
||||
var gcb glfw.MonitorCallback = func(monitor *glfw.Monitor, event glfw.PeripheralEvent) {
|
||||
return func(monitor *glfw.Monitor, event glfw.PeripheralEvent) {
|
||||
var m *Monitor
|
||||
if monitor != nil {
|
||||
m = &Monitor{monitor}
|
||||
}
|
||||
cb(m, PeripheralEvent(event))
|
||||
}
|
||||
monitorCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
||||
func ToScrollCallback(cb func(window *Window, xoff float64, yoff float64)) ScrollCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := ScrollCallback(len(scrollCallbacks) + 1)
|
||||
var gcb glfw.ScrollCallback = func(window *glfw.Window, xoff float64, yoff float64) {
|
||||
return func(window *glfw.Window, xoff float64, yoff float64) {
|
||||
cb(theWindows.get(window), xoff, yoff)
|
||||
}
|
||||
scrollCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
||||
func ToSizeCallback(cb func(window *Window, width int, height int)) SizeCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
id := SizeCallback(len(sizeCallbacks) + 1)
|
||||
var gcb glfw.SizeCallback = func(window *glfw.Window, width, height int) {
|
||||
return func(window *glfw.Window, width, height int) {
|
||||
cb(theWindows.get(window), width, height)
|
||||
}
|
||||
sizeCallbacks[id] = gcb
|
||||
return id
|
||||
}
|
||||
|
@ -18,68 +18,82 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var uniquePtrToCallback = map[uniquePtr]uintptr{}
|
||||
|
||||
func ToCharModsCallback(cb func(window *Window, char rune, mods ModifierKey)) CharModsCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return CharModsCallback(windows.NewCallbackCDecl(func(window uintptr, char rune, mods ModifierKey) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(window uintptr, char rune, mods ModifierKey) uintptr {
|
||||
cb(theGLFWWindows.get(window), char, mods)
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return CharModsCallback(ptr)
|
||||
}
|
||||
|
||||
func ToCloseCallback(cb func(window *Window)) CloseCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return CloseCallback(windows.NewCallbackCDecl(func(window uintptr) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(window uintptr) uintptr {
|
||||
cb(theGLFWWindows.get(window))
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return CloseCallback(ptr)
|
||||
}
|
||||
|
||||
func ToFramebufferSizeCallback(cb func(window *Window, width int, height int)) FramebufferSizeCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return FramebufferSizeCallback(windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr {
|
||||
cb(theGLFWWindows.get(window), width, height)
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return FramebufferSizeCallback(ptr)
|
||||
}
|
||||
|
||||
func ToMonitorCallback(cb func(monitor *Monitor, event PeripheralEvent)) MonitorCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return MonitorCallback(windows.NewCallbackCDecl(func(monitor uintptr, event PeripheralEvent) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(monitor uintptr, event PeripheralEvent) uintptr {
|
||||
var m *Monitor
|
||||
if monitor != 0 {
|
||||
m = &Monitor{monitor}
|
||||
}
|
||||
cb(m, event)
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return MonitorCallback(ptr)
|
||||
}
|
||||
|
||||
func ToScrollCallback(cb func(window *Window, xoff float64, yoff float64)) ScrollCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return ScrollCallback(windows.NewCallbackCDecl(func(window uintptr, xoff *float64, yoff *float64) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(window uintptr, xoff *float64, yoff *float64) uintptr {
|
||||
// xoff and yoff were originally float64, but there is no good way to pass them on 32bit
|
||||
// machines via NewCallback. We've fixed GLFW side to use pointer values.
|
||||
cb(theGLFWWindows.get(window), *xoff, *yoff)
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return ScrollCallback(ptr)
|
||||
}
|
||||
|
||||
func ToSizeCallback(cb func(window *Window, width int, height int)) SizeCallback {
|
||||
if cb == nil {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
return SizeCallback(windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr {
|
||||
ptr := uniquePtr(new(byte))
|
||||
uniquePtrToCallback[ptr] = windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr {
|
||||
cb(theGLFWWindows.get(window), width, height)
|
||||
return 0
|
||||
}))
|
||||
})
|
||||
return SizeCallback(ptr)
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ func (w *Window) SetAttrib(attrib Hint, value int) {
|
||||
}
|
||||
|
||||
func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) {
|
||||
w.w.SetCharModsCallback(charModsCallbacks[cbfun])
|
||||
w.w.SetCharModsCallback(cbfun)
|
||||
return ToCharModsCallback(nil) // TODO
|
||||
}
|
||||
|
||||
@ -179,17 +179,17 @@ func (w *Window) SetCursor(cursor *Cursor) {
|
||||
}
|
||||
|
||||
func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback) {
|
||||
w.w.SetCloseCallback(closeCallbacks[cbfun])
|
||||
w.w.SetCloseCallback(cbfun)
|
||||
return ToCloseCallback(nil) // TODO
|
||||
}
|
||||
|
||||
func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback) {
|
||||
w.w.SetFramebufferSizeCallback(framebufferSizeCallbacks[cbfun])
|
||||
w.w.SetFramebufferSizeCallback(cbfun)
|
||||
return ToFramebufferSizeCallback(nil) // TODO
|
||||
}
|
||||
|
||||
func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback) {
|
||||
w.w.SetScrollCallback(scrollCallbacks[cbfun])
|
||||
w.w.SetScrollCallback(cbfun)
|
||||
return ToScrollCallback(nil) // TODO
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ func (w *Window) SetShouldClose(value bool) {
|
||||
}
|
||||
|
||||
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
|
||||
w.w.SetSizeCallback(sizeCallbacks[cbfun])
|
||||
w.w.SetSizeCallback(cbfun)
|
||||
prev := w.prevSizeCallback
|
||||
w.prevSizeCallback = cbfun
|
||||
return prev
|
||||
@ -302,7 +302,7 @@ func PostEmptyEvent() {
|
||||
}
|
||||
|
||||
func SetMonitorCallback(cbfun MonitorCallback) MonitorCallback {
|
||||
glfw.SetMonitorCallback(monitorCallbacks[cbfun])
|
||||
glfw.SetMonitorCallback(cbfun)
|
||||
return ToMonitorCallback(nil)
|
||||
}
|
||||
|
||||
|
@ -206,13 +206,13 @@ func (w *Window) Restore() {
|
||||
}
|
||||
|
||||
func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) {
|
||||
glfwDLL.call("glfwSetCharModsCallback", w.w, uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetCharModsCallback", w.w, uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
return ToCharModsCallback(nil) // TODO
|
||||
}
|
||||
|
||||
func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback) {
|
||||
glfwDLL.call("glfwSetWindowCloseCallback", w.w, uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetWindowCloseCallback", w.w, uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
return ToCloseCallback(nil) // TODO
|
||||
}
|
||||
@ -226,13 +226,13 @@ func (w *Window) SetCursor(cursor *Cursor) {
|
||||
}
|
||||
|
||||
func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback) {
|
||||
glfwDLL.call("glfwSetFramebufferSizeCallback", w.w, uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetFramebufferSizeCallback", w.w, uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
return ToFramebufferSizeCallback(nil) // TODO
|
||||
}
|
||||
|
||||
func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback) {
|
||||
glfwDLL.call("glfwSetScrollCallback", w.w, uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetScrollCallback", w.w, uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
return ToScrollCallback(nil) // TODO
|
||||
}
|
||||
@ -247,7 +247,7 @@ func (w *Window) SetShouldClose(value bool) {
|
||||
}
|
||||
|
||||
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
|
||||
glfwDLL.call("glfwSetWindowSizeCallback", w.w, uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetWindowSizeCallback", w.w, uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
prev := w.prevSizeCallback
|
||||
w.prevSizeCallback = cbfun
|
||||
@ -413,7 +413,7 @@ func PostEmptyEvent() {
|
||||
}
|
||||
|
||||
func SetMonitorCallback(cbfun MonitorCallback) MonitorCallback {
|
||||
glfwDLL.call("glfwSetMonitorCallback", uintptr(cbfun))
|
||||
glfwDLL.call("glfwSetMonitorCallback", uniquePtrToCallback[uniquePtr(cbfun)])
|
||||
panicError()
|
||||
return ToMonitorCallback(nil) // TODO
|
||||
}
|
||||
|
40
internal/glfw/type_notwindows.go
Normal file
40
internal/glfw/type_notwindows.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !windows && !js
|
||||
// +build !windows,!js
|
||||
|
||||
package glfw
|
||||
|
||||
import (
|
||||
"github.com/go-gl/glfw/v3.3/glfw"
|
||||
)
|
||||
|
||||
type (
|
||||
CharModsCallback = glfw.CharModsCallback
|
||||
CloseCallback = glfw.CloseCallback
|
||||
FramebufferSizeCallback = glfw.FramebufferSizeCallback
|
||||
MonitorCallback = glfw.MonitorCallback
|
||||
ScrollCallback = glfw.ScrollCallback
|
||||
SizeCallback = glfw.SizeCallback
|
||||
)
|
||||
|
||||
type VidMode struct {
|
||||
Width int
|
||||
Height int
|
||||
RedBits int
|
||||
GreenBits int
|
||||
BlueBits int
|
||||
RefreshRate int
|
||||
}
|
@ -17,13 +17,15 @@
|
||||
|
||||
package glfw
|
||||
|
||||
type uniquePtr *byte
|
||||
|
||||
type (
|
||||
CharModsCallback uintptr
|
||||
CloseCallback uintptr
|
||||
FramebufferSizeCallback uintptr
|
||||
MonitorCallback uintptr
|
||||
ScrollCallback uintptr
|
||||
SizeCallback uintptr
|
||||
CharModsCallback uniquePtr
|
||||
CloseCallback uniquePtr
|
||||
FramebufferSizeCallback uniquePtr
|
||||
MonitorCallback uniquePtr
|
||||
ScrollCallback uniquePtr
|
||||
SizeCallback uniquePtr
|
||||
)
|
||||
|
||||
type VidMode struct {
|
@ -687,7 +687,7 @@ func (u *userInterfaceImpl) createWindow(width, height int) error {
|
||||
|
||||
// registerWindowSetSizeCallback must be called from the main thread.
|
||||
func (u *userInterfaceImpl) registerWindowSetSizeCallback() {
|
||||
if u.sizeCallback == 0 {
|
||||
if u.sizeCallback == nil {
|
||||
u.sizeCallback = glfw.ToSizeCallback(func(_ *glfw.Window, width, height int) {
|
||||
if !u.setSizeCallbackEnabled {
|
||||
return
|
||||
@ -734,7 +734,7 @@ func (u *userInterfaceImpl) registerWindowSetSizeCallback() {
|
||||
|
||||
// registerWindowCloseCallback must be called from the main thread.
|
||||
func (u *userInterfaceImpl) registerWindowCloseCallback() {
|
||||
if u.closeCallback == 0 {
|
||||
if u.closeCallback == nil {
|
||||
u.closeCallback = glfw.ToCloseCallback(func(_ *glfw.Window) {
|
||||
u.m.Lock()
|
||||
u.windowBeingClosed = true
|
||||
@ -751,7 +751,7 @@ func (u *userInterfaceImpl) registerWindowCloseCallback() {
|
||||
|
||||
// registerWindowFramebufferSizeCallback must be called from the main thread.
|
||||
func (u *userInterfaceImpl) registerWindowFramebufferSizeCallback() {
|
||||
if u.defaultFramebufferSizeCallback == 0 {
|
||||
if u.defaultFramebufferSizeCallback == nil {
|
||||
// When the window gets resized (either by manual window resize or a window
|
||||
// manager), glfw sends a framebuffer size callback which we need to handle (#1960).
|
||||
// This event is the only way to handle the size change at least on i3 window manager.
|
||||
@ -782,7 +782,7 @@ func (u *userInterfaceImpl) registerWindowFramebufferSizeCallback() {
|
||||
func (u *userInterfaceImpl) waitForFramebufferSizeCallback(window *glfw.Window, f func()) {
|
||||
u.framebufferSizeCallbackCh = make(chan struct{}, 1)
|
||||
|
||||
if u.framebufferSizeCallback == 0 {
|
||||
if u.framebufferSizeCallback == nil {
|
||||
u.framebufferSizeCallback = glfw.ToFramebufferSizeCallback(func(_ *glfw.Window, _, _ int) {
|
||||
// This callback can be invoked multiple times by one PollEvents in theory (#1618).
|
||||
// Allow the case when the channel is full.
|
||||
|
Loading…
Reference in New Issue
Block a user