initial commit
This commit is contained in:
80
events.go
Normal file
80
events.go
Normal file
@ -0,0 +1,80 @@
|
||||
package sati
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
type EventBus struct {
|
||||
mu *sync.Mutex
|
||||
idCounter uint32
|
||||
handlers map[string]map[uint32]func(data any)
|
||||
eventTypes map[string]any
|
||||
}
|
||||
|
||||
type EventHandler struct {
|
||||
id uint32
|
||||
type_ string
|
||||
bus *EventBus
|
||||
}
|
||||
|
||||
func (e *EventHandler) Off() {
|
||||
e.bus.mu.Lock()
|
||||
defer e.bus.mu.Unlock()
|
||||
|
||||
delete(e.bus.handlers[e.type_], e.id)
|
||||
}
|
||||
|
||||
func (e *EventBus) On(event string, handler func(data any)) (*EventHandler, error) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if _, ok := e.eventTypes[event]; !ok {
|
||||
return nil, fmt.Errorf("bad event type")
|
||||
}
|
||||
|
||||
e.idCounter++
|
||||
e.handlers[event][e.idCounter] = handler
|
||||
return &EventHandler{
|
||||
id: e.idCounter,
|
||||
type_: event,
|
||||
bus: e,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *EventBus) dispatch(event string, data any) error {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
formattedData, ok := e.eventTypes[event]
|
||||
if !ok {
|
||||
return fmt.Errorf("bad event type")
|
||||
}
|
||||
|
||||
if err := mapstructure.Decode(data, &formattedData); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, handler := range e.handlers[event] {
|
||||
handler(formattedData)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// eventTypes values must be structs, not pointers
|
||||
func newEventBus(eventTypes map[string]any) *EventBus {
|
||||
e := &EventBus{
|
||||
mu: &sync.Mutex{},
|
||||
handlers: make(map[string]map[uint32]func(data any)),
|
||||
eventTypes: eventTypes,
|
||||
}
|
||||
|
||||
for event := range eventTypes {
|
||||
e.handlers[event] = make(map[uint32]func(data any))
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
Reference in New Issue
Block a user