mirror of
https://github.com/simon-ding/polaris.git
synced 2026-03-04 00:20:47 +08:00
83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package eventbus
|
|
|
|
import (
|
|
"fmt"
|
|
"polaris/pkg/utils"
|
|
"reflect"
|
|
)
|
|
|
|
type EventBus struct {
|
|
handlers utils.Map[string, []EventHandler]
|
|
}
|
|
|
|
type EventHandler struct {
|
|
callback reflect.Value
|
|
async bool
|
|
}
|
|
|
|
func New() *EventBus {
|
|
return &EventBus{
|
|
handlers: utils.Map[string, []EventHandler]{},
|
|
}
|
|
}
|
|
|
|
func (e *EventBus) Subscribe(event string, fn any) error{
|
|
if reflect.TypeOf(fn).Kind() != reflect.Func {
|
|
return fmt.Errorf("handler must be a function: %v", reflect.TypeOf(fn).Kind())
|
|
}
|
|
if handlers, ok := e.handlers.Load(event); ok {
|
|
handlers = append(handlers, EventHandler{
|
|
callback: reflect.ValueOf(fn),})
|
|
e.handlers.Store(event, handlers)
|
|
} else {
|
|
e.handlers.Store(event, []EventHandler{
|
|
{callback: reflect.ValueOf(fn)},
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *EventBus) SubscribeAsync(event string, fn any) error{
|
|
if reflect.TypeOf(fn).Kind() != reflect.Func {
|
|
return fmt.Errorf("handler must be a function: %v", reflect.TypeOf(fn).Kind())
|
|
}
|
|
|
|
if handlers, ok := e.handlers.Load(event); ok {
|
|
handlers = append(handlers, EventHandler{
|
|
callback: reflect.ValueOf(fn), async: true,
|
|
})
|
|
e.handlers.Store(event, handlers)
|
|
} else {
|
|
e.handlers.Store(event, []EventHandler{
|
|
{callback: reflect.ValueOf(fn), async: true},
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *EventBus) Publish(event string, args... any) {
|
|
if handlers, ok := e.handlers.Load(event); ok {
|
|
for _, handler := range handlers {
|
|
args1 := reflectArgs(handler,args...)
|
|
if handler.async {
|
|
go handler.callback.Call(args1)
|
|
} else {
|
|
handler.callback.Call(args1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func reflectArgs(handler EventHandler,args... any) []reflect.Value {
|
|
funcType := handler.callback.Type()
|
|
passedArguments := make([]reflect.Value, len(args))
|
|
for i, v := range args {
|
|
if v == nil {
|
|
passedArguments[i] = reflect.New(funcType.In(i)).Elem()
|
|
} else {
|
|
passedArguments[i] = reflect.ValueOf(v)
|
|
}
|
|
}
|
|
|
|
return passedArguments
|
|
} |