81 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |