callback.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package cgohelper
  2. import (
  3. "sync"
  4. "fmt"
  5. )
  6. var __GlobalCallbackRegistry = CreateCallbackRegistry()
  7. func NewCallback(cb func()) (uint, (func() bool)) {
  8. var id = __GlobalCallbackRegistry.Register(cb)
  9. return id, func() bool {
  10. return __GlobalCallbackRegistry.Unregister(id)
  11. }
  12. }
  13. func GetCallback(id uint) func() {
  14. return __GlobalCallbackRegistry.Get(id)
  15. }
  16. type CallbackRegistry struct {
  17. mutex sync.Mutex
  18. callbacks map[uint] func()
  19. next uint
  20. available [] uint
  21. }
  22. func CreateCallbackRegistry() *CallbackRegistry {
  23. return &CallbackRegistry {
  24. callbacks: make(map[uint]func()),
  25. next: 0,
  26. available: make([] uint, 0),
  27. }
  28. }
  29. func (reg *CallbackRegistry) Register(callback func()) uint {
  30. reg.mutex.Lock()
  31. defer reg.mutex.Unlock()
  32. var id = reg.next
  33. reg.next = (1 + id)
  34. reg.callbacks[id] = callback
  35. return id
  36. }
  37. func (reg *CallbackRegistry) Unregister(id uint) bool {
  38. reg.mutex.Lock()
  39. defer reg.mutex.Unlock()
  40. var _, exists = reg.callbacks[id]
  41. if exists {
  42. delete(reg.callbacks, id)
  43. reg.available = append(reg.available, id)
  44. return true
  45. } else {
  46. return false
  47. }
  48. }
  49. func (reg *CallbackRegistry) Get(id uint) func() {
  50. reg.mutex.Lock()
  51. defer reg.mutex.Unlock()
  52. var callback, exists = reg.callbacks[id]
  53. if exists {
  54. return callback
  55. } else {
  56. panic(fmt.Sprintf("cannot find callback of id %d", id))
  57. }
  58. }