diff options
Diffstat (limited to 'pkg/backend/callbacks.go')
-rw-r--r-- | pkg/backend/callbacks.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/pkg/backend/callbacks.go b/pkg/backend/callbacks.go new file mode 100644 index 0000000..5ea3b04 --- /dev/null +++ b/pkg/backend/callbacks.go @@ -0,0 +1,63 @@ +package backend + +import ( + "fmt" + "reflect" + "sync" + "unsafe" +) + +/* NOTE! ATCHUNG! what follow are not silly comments. Well, *this one* is, but + the lines after this are not. + Those are inline C functions, that are invoked by CGO later on. + it's also crucial that you don't any extra space between the function + block and the 'import "C"' line. */ + +// typedef void (*cb)(); +// inline void _do_callback(cb f) { +// f(); +// } +import "C" + +/* callbacks into C-land */ + +var mut sync.Mutex +var stmut sync.Mutex +var cbs = make(map[string](*[0]byte)) +var initOnce sync.Once + +// Events are just a enumeration of all the posible events that C functions can +// be interested in subscribing to. You cannot subscribe to an event that is +// not listed here. +type Events struct { + OnStatusChanged string +} + +const OnStatusChanged string = "OnStatusChanged" + +// subscribe registers a callback from C-land. +// This callback needs to be passed as a void* C function pointer. +func subscribe(event string, fp unsafe.Pointer) { + mut.Lock() + defer mut.Unlock() + e := &Events{} + v := reflect.Indirect(reflect.ValueOf(&e)) + hf := v.Elem().FieldByName(event) + if reflect.ValueOf(hf).IsZero() { + fmt.Println("ERROR: not a valid event:", event) + } else { + cbs[event] = (*[0]byte)(fp) + } +} + +// trigger fires a callback from C-land. +func trigger(event string) { + mut.Lock() + defer mut.Unlock() + cb := cbs[event] + if cb != nil { + C._do_callback(cb) + } else { + fmt.Println("ERROR: this event does not have subscribers:", event) + } +} |