summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--new/ids.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/new/ids.go b/new/ids.go
new file mode 100644
index 0000000..66dd587
--- /dev/null
+++ b/new/ids.go
@@ -0,0 +1,61 @@
+// 23 february 2015
+
+package ui
+
+// Go pointers cannot be passed to C safely.
+// The Go runtime will move them around, tripping C up.
+// However, C pointers don't have this problem.
+// Solution: use the C pointer to get the Go object needed!
+
+import (
+ "fmt"
+ "sync"
+)
+
+var (
+ ids map[uintptr]interface{}
+ idsLock sync.Mutex
+)
+
+func getGoObject(cptr uintptr) interface{} {
+ idsLock.Lock()
+ defer idsLock.Unlock()
+
+ if i, ok := ids[cptr]; ok {
+ return i
+ }
+ panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p not associated with Go object in package ui", cptr))
+}
+
+func associateGoObject(cptr uintptr, goobj interface{}) {
+ idsLock.Lock()
+ defer idsLock.Unlock()
+
+ if i, ok := ids[cptr]; ok {
+ panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p already associated with Go object of type %T but we want to associate it with Go object of type %T", cptr, i, goobj))
+ }
+ ids[cptr] = goobj
+}
+
+func disassociateGoObject(cptr uintptr) {
+ idsLock.Lock()
+ defer idsLock.Unlock()
+
+ if _, ok := ids[cptr]; !ok {
+ panic(fmt.Errorf("[BUG in package ui; report to andlabs immediately] C pointer %p not associated with any Go object but we want to disassociate it", cptr))
+ }
+ delete(ids, cptr)
+}
+
+func idsHandler(req *request) bool {
+ switch req.id {
+ case reqObjectDestroyed:
+ disassociateGoObject(req.ptr)
+ return true
+ }
+ return false
+}
+
+func init() {
+ interopHandlers = append(interopHandlers, idsHandler)
+}