From ffda9303dfc70dd32046f31d14b1fd0740b14f32 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:44:03 +0200 Subject: [PATCH 1/4] backend: refaactoring - add Backend interface - make GLFW a Backend implementation - redesign APIs --- backend.go | 161 ------------------------------------------- backend_interface.go | 101 +++++++++++++++++++++++++++ examples/main.go | 15 ++-- glfw_backend.go | 150 ++++++++++++++++++++++++++++++++++++++++ texture.go | 4 +- 5 files changed, 261 insertions(+), 170 deletions(-) delete mode 100644 backend.go create mode 100644 backend_interface.go create mode 100644 glfw_backend.go diff --git a/backend.go b/backend.go deleted file mode 100644 index 6883b9a54..000000000 --- a/backend.go +++ /dev/null @@ -1,161 +0,0 @@ -//go:build !exclude_cimgui_glfw -// +build !exclude_cimgui_glfw - -package imgui - -// #cgo amd64,linux LDFLAGS: ${SRCDIR}/lib/linux/x64/libglfw3.a -ldl -lGL -lX11 -// #cgo amd64,windows LDFLAGS: -L${SRCDIR}/lib/windows/x64 -l:libglfw3.a -lgdi32 -lopengl32 -limm32 -// #cgo darwin LDFLAGS: -framework Cocoa -framework IOKit -framework CoreVideo -// #cgo amd64,darwin LDFLAGS: ${SRCDIR}/lib/macos/x64/libglfw3.a -// #cgo arm64,darwin LDFLAGS: ${SRCDIR}/lib/macos/arm64/libglfw3.a -// #cgo !gles2,darwin LDFLAGS: -framework OpenGL -// #cgo gles2,darwin LDFLAGS: -lGLESv2 -// #cgo CPPFLAGS: -DCIMGUI_GO_USE_GLFW -// extern void glfwWindowLoopCallback(); -// extern void glfwBeforeRender(); -// extern void glfwAfterRender(); -// extern void glfwAfterCreateContext(); -// extern void glfwBeforeDestoryContext(); -// #include -// #include "backend.h" -import "C" - -import ( - "image" - "unsafe" -) - -type GLFWWindowFlags int - -const ( - GLFWWindowFlagsNone GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsNone) - GLFWWindowFlagsNotResizable GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsNotResizable) - GLFWWindowFlagsMaximized GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsMaximized) - GLFWWindowFlagsFloating GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsFloating) - GLFWWindowFlagsFrameless GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsFrameless) - GLFWWindowFlagsTransparent GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsTransparent) -) - -type voidCallbackFunc func() - -var ( - afterCreateContext voidCallbackFunc - loopFunc voidCallbackFunc - beforeRender voidCallbackFunc - afterRender voidCallbackFunc - beforeDestoryContext voidCallbackFunc -) - -type GLFWwindow uintptr - -func (w GLFWwindow) handle() *C.GLFWwindow { - return (*C.GLFWwindow)(unsafe.Pointer(w)) -} - -func SetAfterCreateContextHook(hook func()) { - afterCreateContext = hook -} - -func SetBeforeDestroyContextHook(hook func()) { - beforeDestoryContext = hook -} - -func SetBeforeRenderHook(hook func()) { - beforeRender = hook -} - -func SetAfterRenderHook(hook func()) { - afterRender = hook -} - -func SetBgColor(color Vec4) { - C.igSetBgColor(color.toC()) -} - -func (w GLFWwindow) Run(loop func()) { - loopFunc = loop - C.igRunLoop(w.handle(), C.VoidCallback(C.glfwWindowLoopCallback), C.VoidCallback(C.glfwBeforeRender), C.VoidCallback(C.glfwAfterRender), C.VoidCallback(C.glfwBeforeDestoryContext)) -} - -func (w GLFWwindow) DisplaySize() (width int32, height int32) { - widthArg, widthFin := wrapNumberPtr[C.int, int32](&width) - defer widthFin() - - heightArg, heightFin := wrapNumberPtr[C.int, int32](&height) - defer heightFin() - - C.igGLFWWindow_GetDisplaySize(w.handle(), widthArg, heightArg) - - return -} - -func (w GLFWwindow) SetShouldClose(value bool) { - C.igGLFWWindow_SetShouldClose(w.handle(), C.int(castBool(value))) -} - -//export glfwWindowLoopCallback -func glfwWindowLoopCallback() { - if loopFunc != nil { - loopFunc() - } -} - -//export glfwBeforeRender -func glfwBeforeRender() { - if beforeRender != nil { - beforeRender() - } -} - -//export glfwAfterRender -func glfwAfterRender() { - if afterRender != nil { - afterRender() - } -} - -//export glfwAfterCreateContext -func glfwAfterCreateContext() { - if afterCreateContext != nil { - afterCreateContext() - } -} - -//export glfwBeforeDestoryContext -func glfwBeforeDestoryContext() { - if beforeDestoryContext != nil { - beforeDestoryContext() - } -} - -func CreateGlfwWindow(title string, width, height int, flags GLFWWindowFlags) GLFWwindow { - titleArg, titleFin := wrapString(title) - defer titleFin() - - window := GLFWwindow(unsafe.Pointer(C.igCreateGLFWWindow(titleArg, C.int(width), C.int(height), C.GLFWWindowFlags(flags), C.VoidCallback(C.glfwAfterCreateContext)))) - if window == 0 { - panic("Failed to create GLFW window") - } - - return window -} - -func SetTargetFPS(fps uint) { - C.igSetTargetFPS(C.uint(fps)) -} - -func Refresh() { - C.igRefresh() -} - -func CreateTexture(pixels unsafe.Pointer, width, height int) TextureID { - return TextureID(C.igCreateTexture((*C.uchar)(pixels), C.int(width), C.int(height))) -} - -func CreateTextureRgba(img *image.RGBA, width, height int) TextureID { - return TextureID(C.igCreateTexture((*C.uchar)(&(img.Pix[0])), C.int(width), C.int(height))) -} - -func DeleteTexture(id TextureID) { - C.igDeleteTexture(C.ImTextureID(id)) -} diff --git a/backend_interface.go b/backend_interface.go new file mode 100644 index 000000000..d904684f2 --- /dev/null +++ b/backend_interface.go @@ -0,0 +1,101 @@ +package imgui + +// extern void loopCallback(); +// extern void beforeRender(); +// extern void afterRender(); +// extern void afterCreateContext(); +// extern void beforeDestoryContext(); +import "C" + +import ( + "image" + "unsafe" +) + +var currentBackend Backend + +//export loopCallback +func loopCallback() { + if currentBackend != nil { + if f := currentBackend.loopFunc(); f != nil { + f() + } + } +} + +//export beforeRender +func beforeRender() { + if currentBackend != nil { + if f := currentBackend.beforeRenderHook(); f != nil { + f() + } + } +} + +//export afterRender +func afterRender() { + if currentBackend != nil { + if f := currentBackend.afterRenderHook(); f != nil { + f() + } + } +} + +//export afterCreateContext +func afterCreateContext() { + if currentBackend != nil { + if f := currentBackend.afterCreateHook(); f != nil { + f() + } + } +} + +//export beforeDestoryContext +func beforeDestoryContext() { + if currentBackend != nil { + if f := currentBackend.beforeDestroyHook(); f != nil { + f() + } + } +} + +// Backend is a special interface that implements all methods required +// to render imgui application. +type Backend interface { + SetAfterCreateContextHook(func()) + SetBeforeDestroyContextHook(func()) + SetBeforeRenderHook(func()) + SetAfterRenderHook(func()) + + SetBgColor(color Vec4) + Run(func()) + Refresh() + + DisplaySize() (width, height int32) + SetShouldClose(bool) + + SetTargetFPS(fps uint) + + CreateTexture(pixels unsafe.Pointer, width, Height int) TextureID + CreateTextureRgba(img *image.RGBA, width, height int) TextureID + DeleteTexture(id TextureID) + + // TODO: flags needs generic layer + CreateWindow(title string, width, height int, flags GLFWWindowFlags) + + // for C callbacks + afterCreateHook() func() + beforeRenderHook() func() + loopFunc() func() + afterRenderHook() func() + beforeDestroyHook() func() +} + +func CreateBackend( /*TODO: backend type*/ ) Backend { + currentBackend = &GLFWBackend{} + return currentBackend +} + +func GetBackend() Backend { + return currentBackend +} diff --git a/examples/main.go b/examples/main.go index 985f9ccdc..75afab394 100644 --- a/examples/main.go +++ b/examples/main.go @@ -20,7 +20,7 @@ var ( a float32 color4 [4]float32 = [4]float32{r, g, b, a} selected bool - window imgui.GLFWwindow + backend imgui.Backend img *image.RGBA texture *imgui.Texture barValues []int64 @@ -39,7 +39,7 @@ func showWidgetsDemo() { imgui.SetNextWindowSizeV(imgui.NewVec2(300, 300), imgui.CondOnce) imgui.Begin("Window 1") if imgui.ButtonV("Click Me", imgui.NewVec2(80, 20)) { - w, h := window.DisplaySize() + w, h := backend.DisplaySize() fmt.Println(w, h) } imgui.TextUnformatted("Unformatted text") @@ -120,12 +120,13 @@ func main() { barValues = append(barValues, int64(i+1)) } - imgui.SetAfterCreateContextHook(afterCreateContext) - imgui.SetBeforeDestroyContextHook(beforeDestroyContext) + backend = imgui.CreateBackend() + backend.SetAfterCreateContextHook(afterCreateContext) + backend.SetBeforeDestroyContextHook(beforeDestroyContext) - imgui.SetBgColor(imgui.NewVec4(0.45, 0.55, 0.6, 1.0)) + backend.SetBgColor(imgui.NewVec4(0.45, 0.55, 0.6, 1.0)) - window = imgui.CreateGlfwWindow("Hello from cimgui-go", 1200, 900, 0) + backend.CreateWindow("Hello from cimgui-go", 1200, 900, 0) - window.Run(loop) + backend.Run(loop) } diff --git a/glfw_backend.go b/glfw_backend.go new file mode 100644 index 000000000..985996ef0 --- /dev/null +++ b/glfw_backend.go @@ -0,0 +1,150 @@ +//go:build !exclude_cimgui_glfw +// +build !exclude_cimgui_glfw + +package imgui + +// #cgo amd64,linux LDFLAGS: ${SRCDIR}/lib/linux/x64/libglfw3.a -ldl -lGL -lX11 +// #cgo amd64,windows LDFLAGS: -L${SRCDIR}/lib/windows/x64 -l:libglfw3.a -lgdi32 -lopengl32 -limm32 +// #cgo darwin LDFLAGS: -framework Cocoa -framework IOKit -framework CoreVideo +// #cgo amd64,darwin LDFLAGS: ${SRCDIR}/lib/macos/x64/libglfw3.a +// #cgo arm64,darwin LDFLAGS: ${SRCDIR}/lib/macos/arm64/libglfw3.a +// #cgo !gles2,darwin LDFLAGS: -framework OpenGL +// #cgo gles2,darwin LDFLAGS: -lGLESv2 +// #cgo CPPFLAGS: -DCIMGUI_GO_USE_GLFW +// extern void loopCallback(); +// extern void beforeRender(); +// extern void afterRender(); +// extern void afterCreateContext(); +// extern void beforeDestoryContext(); +// #include +// #include "backend.h" +import "C" + +import ( + "image" + "unsafe" +) + +type GLFWWindowFlags int + +const ( + GLFWWindowFlagsNone GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsNone) + GLFWWindowFlagsNotResizable GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsNotResizable) + GLFWWindowFlagsMaximized GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsMaximized) + GLFWWindowFlagsFloating GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsFloating) + GLFWWindowFlagsFrameless GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsFrameless) + GLFWWindowFlagsTransparent GLFWWindowFlags = GLFWWindowFlags(C.GLFWWindowFlagsTransparent) +) + +type voidCallbackFunc func() + +type GLFWBackend struct { + afterCreateContext voidCallbackFunc + loop voidCallbackFunc + beforeRender voidCallbackFunc + afterRender voidCallbackFunc + beforeDestoryContext voidCallbackFunc + window uintptr +} + +func (b *GLFWBackend) handle() *C.GLFWwindow { + return (*C.GLFWwindow)(unsafe.Pointer(b.window)) +} + +func (b *GLFWBackend) SetAfterCreateContextHook(hook func()) { + b.afterCreateContext = hook +} + +func (b *GLFWBackend) afterCreateHook() func() { + return b.afterCreateContext +} + +func (b *GLFWBackend) SetBeforeDestroyContextHook(hook func()) { + b.beforeDestoryContext = hook +} + +func (b *GLFWBackend) beforeDestroyHook() func() { + return b.beforeDestoryContext +} + +func (b *GLFWBackend) SetBeforeRenderHook(hook func()) { + b.beforeRender = hook +} + +func (b *GLFWBackend) beforeRenderHook() func() { + return b.beforeRender +} + +func (b *GLFWBackend) SetAfterRenderHook(hook func()) { + b.afterRender = hook +} + +func (b *GLFWBackend) afterRenderHook() func() { + return b.afterRender +} + +func (b *GLFWBackend) SetBgColor(color Vec4) { + C.igSetBgColor(color.toC()) +} + +func (b *GLFWBackend) Run(loop func()) { + b.loop = loop + C.igRunLoop(b.handle(), C.VoidCallback(C.loopCallback), C.VoidCallback(C.beforeRender), C.VoidCallback(C.afterRender), C.VoidCallback(C.beforeDestoryContext)) +} + +func (b *GLFWBackend) loopFunc() func() { + return b.loop +} + +func (b GLFWBackend) DisplaySize() (width int32, height int32) { + widthArg, widthFin := wrapNumberPtr[C.int, int32](&width) + defer widthFin() + + heightArg, heightFin := wrapNumberPtr[C.int, int32](&height) + defer heightFin() + + C.igGLFWWindow_GetDisplaySize(b.handle(), widthArg, heightArg) + + return +} + +func (b GLFWBackend) SetShouldClose(value bool) { + C.igGLFWWindow_SetShouldClose(b.handle(), C.int(castBool(value))) +} + +func (b *GLFWBackend) CreateWindow(title string, width, height int, flags GLFWWindowFlags) { + titleArg, titleFin := wrapString(title) + defer titleFin() + + //b.window = uintptr(unsafe.Pointer(C.igCreateGLFWWindow(titleArg, C.int(width), C.int(height), C.GLFWWindowFlags(flags), C.VoidCallback(C.afterCreateContext)))) + b.window = uintptr(unsafe.Pointer(C.igCreateGLFWWindow( + titleArg, + C.int(width), + C.int(height), + C.GLFWWindowFlags(flags), + C.VoidCallback(C.afterCreateContext), + ))) + if b.window == 0 { + panic("Failed to create GLFW window") + } +} + +func (b *GLFWBackend) SetTargetFPS(fps uint) { + C.igSetTargetFPS(C.uint(fps)) +} + +func (b *GLFWBackend) Refresh() { + C.igRefresh() +} + +func (b *GLFWBackend) CreateTexture(pixels unsafe.Pointer, width, height int) TextureID { + return TextureID(C.igCreateTexture((*C.uchar)(pixels), C.int(width), C.int(height))) +} + +func (b *GLFWBackend) CreateTextureRgba(img *image.RGBA, width, height int) TextureID { + return TextureID(C.igCreateTexture((*C.uchar)(&(img.Pix[0])), C.int(width), C.int(height))) +} + +func (b *GLFWBackend) DeleteTexture(id TextureID) { + C.igDeleteTexture(C.ImTextureID(id)) +} diff --git a/texture.go b/texture.go index fadb0679e..72651a43b 100644 --- a/texture.go +++ b/texture.go @@ -21,7 +21,7 @@ type Texture struct { } func NewTextureFromRgba(rgba *image.RGBA) *Texture { - texID := CreateTextureRgba(rgba, rgba.Bounds().Dx(), rgba.Bounds().Dy()) + texID := currentBackend.CreateTextureRgba(rgba, rgba.Bounds().Dx(), rgba.Bounds().Dy()) if texID == nil { return nil @@ -40,7 +40,7 @@ func NewTextureFromRgba(rgba *image.RGBA) *Texture { } func (t *Texture) release() { - DeleteTexture(t.id) + currentBackend.DeleteTexture(t.id) } func (t *Texture) ID() TextureID { From 433cfa3622be6f0560a22e621e81fb2c51923718 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:44:36 +0200 Subject: [PATCH 2/4] rename: backend{_interface => }.go --- backend.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 backend.go diff --git a/backend.go b/backend.go new file mode 100644 index 000000000..d904684f2 --- /dev/null +++ b/backend.go @@ -0,0 +1,101 @@ +package imgui + +// extern void loopCallback(); +// extern void beforeRender(); +// extern void afterRender(); +// extern void afterCreateContext(); +// extern void beforeDestoryContext(); +import "C" + +import ( + "image" + "unsafe" +) + +var currentBackend Backend + +//export loopCallback +func loopCallback() { + if currentBackend != nil { + if f := currentBackend.loopFunc(); f != nil { + f() + } + } +} + +//export beforeRender +func beforeRender() { + if currentBackend != nil { + if f := currentBackend.beforeRenderHook(); f != nil { + f() + } + } +} + +//export afterRender +func afterRender() { + if currentBackend != nil { + if f := currentBackend.afterRenderHook(); f != nil { + f() + } + } +} + +//export afterCreateContext +func afterCreateContext() { + if currentBackend != nil { + if f := currentBackend.afterCreateHook(); f != nil { + f() + } + } +} + +//export beforeDestoryContext +func beforeDestoryContext() { + if currentBackend != nil { + if f := currentBackend.beforeDestroyHook(); f != nil { + f() + } + } +} + +// Backend is a special interface that implements all methods required +// to render imgui application. +type Backend interface { + SetAfterCreateContextHook(func()) + SetBeforeDestroyContextHook(func()) + SetBeforeRenderHook(func()) + SetAfterRenderHook(func()) + + SetBgColor(color Vec4) + Run(func()) + Refresh() + + DisplaySize() (width, height int32) + SetShouldClose(bool) + + SetTargetFPS(fps uint) + + CreateTexture(pixels unsafe.Pointer, width, Height int) TextureID + CreateTextureRgba(img *image.RGBA, width, height int) TextureID + DeleteTexture(id TextureID) + + // TODO: flags needs generic layer + CreateWindow(title string, width, height int, flags GLFWWindowFlags) + + // for C callbacks + afterCreateHook() func() + beforeRenderHook() func() + loopFunc() func() + afterRenderHook() func() + beforeDestroyHook() func() +} + +func CreateBackend( /*TODO: backend type*/ ) Backend { + currentBackend = &GLFWBackend{} + return currentBackend +} + +func GetBackend() Backend { + return currentBackend +} From 8826e6f5597da5dcc843b29c4f954e4d72a9c9e5 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:48:42 +0200 Subject: [PATCH 3/4] rename: { => glfw_}backend.(cpp/h) --- backend_interface.go | 101 -------------------------------- backend.cpp => glfw_backend.cpp | 2 +- glfw_backend.go | 4 +- backend.h => glfw_backend.h | 0 4 files changed, 3 insertions(+), 104 deletions(-) delete mode 100644 backend_interface.go rename backend.cpp => glfw_backend.cpp (99%) rename backend.h => glfw_backend.h (100%) diff --git a/backend_interface.go b/backend_interface.go deleted file mode 100644 index d904684f2..000000000 --- a/backend_interface.go +++ /dev/null @@ -1,101 +0,0 @@ -package imgui - -// extern void loopCallback(); -// extern void beforeRender(); -// extern void afterRender(); -// extern void afterCreateContext(); -// extern void beforeDestoryContext(); -import "C" - -import ( - "image" - "unsafe" -) - -var currentBackend Backend - -//export loopCallback -func loopCallback() { - if currentBackend != nil { - if f := currentBackend.loopFunc(); f != nil { - f() - } - } -} - -//export beforeRender -func beforeRender() { - if currentBackend != nil { - if f := currentBackend.beforeRenderHook(); f != nil { - f() - } - } -} - -//export afterRender -func afterRender() { - if currentBackend != nil { - if f := currentBackend.afterRenderHook(); f != nil { - f() - } - } -} - -//export afterCreateContext -func afterCreateContext() { - if currentBackend != nil { - if f := currentBackend.afterCreateHook(); f != nil { - f() - } - } -} - -//export beforeDestoryContext -func beforeDestoryContext() { - if currentBackend != nil { - if f := currentBackend.beforeDestroyHook(); f != nil { - f() - } - } -} - -// Backend is a special interface that implements all methods required -// to render imgui application. -type Backend interface { - SetAfterCreateContextHook(func()) - SetBeforeDestroyContextHook(func()) - SetBeforeRenderHook(func()) - SetAfterRenderHook(func()) - - SetBgColor(color Vec4) - Run(func()) - Refresh() - - DisplaySize() (width, height int32) - SetShouldClose(bool) - - SetTargetFPS(fps uint) - - CreateTexture(pixels unsafe.Pointer, width, Height int) TextureID - CreateTextureRgba(img *image.RGBA, width, height int) TextureID - DeleteTexture(id TextureID) - - // TODO: flags needs generic layer - CreateWindow(title string, width, height int, flags GLFWWindowFlags) - - // for C callbacks - afterCreateHook() func() - beforeRenderHook() func() - loopFunc() func() - afterRenderHook() func() - beforeDestroyHook() func() -} - -func CreateBackend( /*TODO: backend type*/ ) Backend { - currentBackend = &GLFWBackend{} - return currentBackend -} - -func GetBackend() Backend { - return currentBackend -} diff --git a/backend.cpp b/glfw_backend.cpp similarity index 99% rename from backend.cpp rename to glfw_backend.cpp index ae131ff20..38ffce32e 100644 --- a/backend.cpp +++ b/glfw_backend.cpp @@ -3,7 +3,7 @@ #define CIMGUI_USE_GLFW #define CIMGUI_USE_OPENGL3 -#include "backend.h" +#include "glfw_backend.h" #include "cimgui/cimgui.h" #include "cimgui/cimgui_impl.h" #include "thirdparty/glfw/include/GLFW/glfw3.h" // Will drag system OpenGL headers diff --git a/glfw_backend.go b/glfw_backend.go index 985996ef0..ac8ddd9cf 100644 --- a/glfw_backend.go +++ b/glfw_backend.go @@ -17,7 +17,7 @@ package imgui // extern void afterCreateContext(); // extern void beforeDestoryContext(); // #include -// #include "backend.h" +// #include "glfw_backend.h" import "C" import ( @@ -116,7 +116,7 @@ func (b *GLFWBackend) CreateWindow(title string, width, height int, flags GLFWWi titleArg, titleFin := wrapString(title) defer titleFin() - //b.window = uintptr(unsafe.Pointer(C.igCreateGLFWWindow(titleArg, C.int(width), C.int(height), C.GLFWWindowFlags(flags), C.VoidCallback(C.afterCreateContext)))) + // b.window = uintptr(unsafe.Pointer(C.igCreateGLFWWindow(titleArg, C.int(width), C.int(height), C.GLFWWindowFlags(flags), C.VoidCallback(C.afterCreateContext)))) b.window = uintptr(unsafe.Pointer(C.igCreateGLFWWindow( titleArg, C.int(width), diff --git a/backend.h b/glfw_backend.h similarity index 100% rename from backend.h rename to glfw_backend.h From 235cb6c726f3fc3bf381f10d84574db4bf608a63 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:01:42 +0200 Subject: [PATCH 4/4] backend: add comment --- backend.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend.go b/backend.go index d904684f2..62d378924 100644 --- a/backend.go +++ b/backend.go @@ -84,6 +84,15 @@ type Backend interface { CreateWindow(title string, width, height int, flags GLFWWindowFlags) // for C callbacks + // What happens here is a bit tricky: + // - user sets these callbacks via Set* methods of the backend + // - callbacks are stored in currentContext variable + // - functions below just returns that callbacks + // - on top of this file is a set of global function with names similar to these below + // - these functions are exported to C + // - backend implementation uses C references to Go callbacks to share them (again ;-) ) + // into backend code. + // As you can see this is all to convert Go callback int C callback afterCreateHook() func() beforeRenderHook() func() loopFunc() func()