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  }