This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository ego.
View the commit online.
commit 42d7631e975641aa39188af9fd1247570373e62f
Author: [email protected] <[email protected]>
AuthorDate: Mon Mar 30 21:46:11 2026 -0600
feat(efl): add generalized callback map for function pointer bridging
Add CallbackRegister/Lookup/Remove in efl/callback.go for storing
Go closures keyed by ID, enabling C trampolines to dispatch to
typed Go functions via the void *data pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
efl/callback.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++
efl/callback_test.go | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/efl/callback.go b/efl/callback.go
new file mode 100644
index 0000000..0bf66a9
--- /dev/null
+++ b/efl/callback.go
@@ -0,0 +1,47 @@
+package efl
+
+import (
+ "sync"
+ "sync/atomic"
+)
+
+// Generalized callback registration map — stores Go closures keyed by
+// unique ID. The ID is passed as void* data to C, and the trampoline
+// uses CallbackLookup to retrieve the Go closure. This is separate from
+// the event callback map in event.go to avoid coupling the two systems.
+var (
+ funcCbMu sync.RWMutex
+ funcCbMap = make(map[uintptr]any)
+ funcCbSeq atomic.Uintptr
+)
+
+// CallbackRegister stores a Go closure and returns a unique ID to pass
+// as void *data to C. The closure can be any func(...) type.
+func CallbackRegister(fn any) uintptr {
+ id := funcCbSeq.Add(1)
+ funcCbMu.Lock()
+ funcCbMap[id] = fn
+ funcCbMu.Unlock()
+ return id
+}
+
+// CallbackLookup retrieves a Go closure by ID with type assertion.
+// Returns the zero value of T if the ID is not found.
+func CallbackLookup[T any](id uintptr) T {
+ funcCbMu.RLock()
+ v := funcCbMap[id]
+ funcCbMu.RUnlock()
+ if v == nil {
+ var zero T
+ return zero
+ }
+ return v.(T)
+}
+
+// CallbackRemove deletes a callback from the map. Called by the
+// egoCallbackFree C trampoline when EFL invokes the free_cb.
+func CallbackRemove(id uintptr) {
+ funcCbMu.Lock()
+ delete(funcCbMap, id)
+ funcCbMu.Unlock()
+}
diff --git a/efl/callback_test.go b/efl/callback_test.go
new file mode 100644
index 0000000..56cfebc
--- /dev/null
+++ b/efl/callback_test.go
@@ -0,0 +1,34 @@
+package efl
+
+import "testing"
+
+func TestCallbackRegisterAndLookup(t *testing.T) {
+ fn := func(a, b string) { _ = a + b }
+ id := CallbackRegister(fn)
+ if id == 0 {
+ t.Fatal("CallbackRegister returned 0")
+ }
+
+ got := CallbackLookup[func(string, string)](id)
+ if got == nil {
+ t.Fatal("CallbackLookup returned nil")
+ }
+}
+
+func TestCallbackRemove(t *testing.T) {
+ fn := func() {}
+ id := CallbackRegister(fn)
+ CallbackRemove(id)
+
+ got := CallbackLookup[func()](id)
+ if got != nil {
+ t.Fatal("CallbackLookup should return nil after remove")
+ }
+}
+
+func TestCallbackLookupMissing(t *testing.T) {
+ got := CallbackLookup[func()](99999)
+ if got != nil {
+ t.Fatal("CallbackLookup should return nil for unknown ID")
+ }
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.