feat: simple eventbus

This commit is contained in:
Simon Ding
2025-04-08 17:46:07 +08:00
parent 2bc71b0c66
commit 59fa91a3bf

83
pkg/eventbus/eventbus.go Normal file
View File

@@ -0,0 +1,83 @@
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
}