100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
package serverevents
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
var emitter *EventEmitter
|
|
|
|
type Subscription struct {
|
|
id string
|
|
eventType string
|
|
todo func(Event)
|
|
emitter *EventEmitter
|
|
}
|
|
|
|
func (sub Subscription) Unsubscribe() {
|
|
if len(sub.eventType) < 1 {
|
|
emitter.onAllSubscribers = slices.DeleteFunc(emitter.onAllSubscribers, func(existSub Subscription) bool {
|
|
return existSub.id == sub.id
|
|
})
|
|
return
|
|
}
|
|
eventSubscribers := emitter.subscribers[sub.eventType]
|
|
if eventSubscribers == nil || len(eventSubscribers) < 1 {
|
|
return
|
|
}
|
|
emitter.subscribers[sub.eventType] = slices.DeleteFunc(emitter.subscribers[sub.eventType], func(existSub Subscription) bool {
|
|
return existSub.id == sub.id
|
|
})
|
|
}
|
|
|
|
type Event struct {
|
|
Type string `json:"type"`
|
|
Data any `json:"data"`
|
|
IsBackendOnly bool `json:"-"`
|
|
}
|
|
|
|
type EventEmitter struct {
|
|
subscribers map[string][]Subscription
|
|
onAllSubscribers []Subscription
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func GetEventEmitter() *EventEmitter {
|
|
if emitter == nil {
|
|
emitter = &EventEmitter{
|
|
subscribers: make(map[string][]Subscription),
|
|
onAllSubscribers: make([]Subscription, 0),
|
|
}
|
|
}
|
|
return emitter
|
|
}
|
|
|
|
func (em *EventEmitter) On(eventType string, do func(Event)) Subscription {
|
|
em.mu.Lock()
|
|
defer em.mu.Unlock()
|
|
|
|
if em.subscribers[eventType] == nil {
|
|
em.subscribers[eventType] = make([]Subscription, 0)
|
|
}
|
|
sub := Subscription{
|
|
id: uuid.NewString(),
|
|
eventType: eventType,
|
|
todo: do,
|
|
emitter: em,
|
|
}
|
|
em.subscribers[eventType] = append(em.subscribers[eventType], sub)
|
|
return sub
|
|
}
|
|
|
|
func (em *EventEmitter) OnAll(do func(Event)) Subscription {
|
|
em.mu.Lock()
|
|
defer em.mu.Unlock()
|
|
|
|
sub := Subscription{
|
|
id: uuid.NewString(),
|
|
todo: do,
|
|
emitter: em,
|
|
}
|
|
em.onAllSubscribers = append(em.onAllSubscribers, sub)
|
|
return sub
|
|
}
|
|
|
|
func (em *EventEmitter) Emit(event Event) {
|
|
executeSubscribers(em.onAllSubscribers, event)
|
|
eventSubscribers := em.subscribers[event.Type]
|
|
if eventSubscribers != nil {
|
|
executeSubscribers(eventSubscribers, event)
|
|
}
|
|
}
|
|
|
|
func executeSubscribers(toDos []Subscription, event Event) {
|
|
for _, sub := range toDos {
|
|
sub.todo(event)
|
|
}
|
|
}
|