90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package serverevents
|
|
|
|
import (
|
|
di "git.apihub24.de/admin/generic-di"
|
|
"github.com/google/uuid"
|
|
"slices"
|
|
"sync"
|
|
)
|
|
|
|
func init() {
|
|
di.Injectable(newEventEmitter)
|
|
}
|
|
|
|
type IEventEmitter interface {
|
|
On(eventType string, do func(Event)) Subscription
|
|
OnAll(do func(Event)) Subscription
|
|
Emit(event Event)
|
|
Unsubscribe(Subscription)
|
|
}
|
|
|
|
type eventEmitter struct {
|
|
subscribers map[string][]Subscription
|
|
onAllSubscribers []Subscription
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func newEventEmitter() IEventEmitter {
|
|
return &eventEmitter{}
|
|
}
|
|
|
|
func (emitter *eventEmitter) On(eventType string, do func(Event)) Subscription {
|
|
emitter.mu.Lock()
|
|
defer emitter.mu.Unlock()
|
|
|
|
if emitter.subscribers[eventType] == nil {
|
|
emitter.subscribers[eventType] = make([]Subscription, 0)
|
|
}
|
|
sub := Subscription{
|
|
id: uuid.NewString(),
|
|
eventType: eventType,
|
|
todo: do,
|
|
emitter: emitter,
|
|
}
|
|
emitter.subscribers[eventType] = append(emitter.subscribers[eventType], sub)
|
|
return sub
|
|
}
|
|
|
|
func (emitter *eventEmitter) OnAll(do func(Event)) Subscription {
|
|
emitter.mu.Lock()
|
|
defer emitter.mu.Unlock()
|
|
|
|
sub := Subscription{
|
|
id: uuid.NewString(),
|
|
todo: do,
|
|
emitter: emitter,
|
|
}
|
|
emitter.onAllSubscribers = append(emitter.onAllSubscribers, sub)
|
|
return sub
|
|
}
|
|
|
|
func (emitter *eventEmitter) Emit(event Event) {
|
|
emitter.executeSubscribers(emitter.onAllSubscribers, event)
|
|
eventSubscribers := emitter.subscribers[event.Type]
|
|
if eventSubscribers != nil {
|
|
emitter.executeSubscribers(eventSubscribers, event)
|
|
}
|
|
}
|
|
|
|
func (emitter *eventEmitter) Unsubscribe(subscription Subscription) {
|
|
if len(subscription.eventType) < 1 {
|
|
emitter.onAllSubscribers = slices.DeleteFunc(emitter.onAllSubscribers, func(existSub Subscription) bool {
|
|
return existSub.id == subscription.id
|
|
})
|
|
return
|
|
}
|
|
eventSubscribers := emitter.subscribers[subscription.eventType]
|
|
if eventSubscribers == nil || len(eventSubscribers) < 1 {
|
|
return
|
|
}
|
|
emitter.subscribers[subscription.eventType] = slices.DeleteFunc(emitter.subscribers[subscription.eventType], func(existSub Subscription) bool {
|
|
return existSub.id == subscription.id
|
|
})
|
|
}
|
|
|
|
func (emitter *eventEmitter) executeSubscribers(toDos []Subscription, event Event) {
|
|
for _, sub := range toDos {
|
|
sub.todo(event)
|
|
}
|
|
}
|