github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/event.go (about) 1 package kiwi 2 3 import ( 4 "reflect" 5 6 "github.com/15mga/kiwi/ds" 7 8 "github.com/15mga/kiwi/util" 9 ) 10 11 var ( 12 _Dispatcher = NewDispatcher[util.M](util.M{}) 13 ) 14 15 func Event() *Dispatcher[util.M] { 16 return _Dispatcher 17 } 18 19 func BindEvent(name string, handler EventHandler[util.M]) { 20 _Dispatcher.Bind(name, handler) 21 } 22 23 func UnbindEvent(name string, handler EventHandler[util.M]) { 24 _Dispatcher.Unbind(name, handler) 25 } 26 27 func DispatchEvent(name string, data any) { 28 _Dispatcher.Dispatch(name, data) 29 } 30 31 func NewDispatcher[T any](data T) *Dispatcher[T] { 32 return &Dispatcher[T]{ 33 data: data, 34 nameToHandler: make(map[string]*ds.Link[EventHandler[T]]), 35 } 36 } 37 38 type EventHandler[T any] func(T, any) 39 40 type Dispatcher[T any] struct { 41 data T 42 nameToHandler map[string]*ds.Link[EventHandler[T]] 43 } 44 45 func (d *Dispatcher[T]) Bind(name string, handler EventHandler[T]) { 46 link, ok := d.nameToHandler[name] 47 if !ok { 48 link = ds.NewLink[EventHandler[T]]() 49 d.nameToHandler[name] = link 50 } 51 link.Push(handler) 52 } 53 54 func (d *Dispatcher[T]) Unbind(name string, handler EventHandler[T]) { 55 link, ok := d.nameToHandler[name] 56 if !ok { 57 return 58 } 59 pointer := reflect.ValueOf(handler).Pointer() 60 _ = link.Del(func(fn EventHandler[T]) bool { 61 return reflect.ValueOf(fn).Pointer() == pointer 62 }) 63 } 64 65 func (d *Dispatcher[T]) Dispatch(name string, data any) { 66 link, ok := d.nameToHandler[name] 67 if !ok { 68 return 69 } 70 link.Iter(func(handler EventHandler[T]) { 71 handler(d.data, data) 72 }) 73 }