mirror of
https://github.com/simon-ding/polaris.git
synced 2026-02-06 23:21:00 +08:00
feat: simple eventbus
This commit is contained in:
83
pkg/eventbus/eventbus.go
Normal file
83
pkg/eventbus/eventbus.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user