package ui import ( "fmt" "sync" "github.com/nmoniz/gubgub" ) var eventBusGetter = sync.OnceValue(func() *eventBus { return NewSyncEventBus() }) func EventBus() *eventBus { return eventBusGetter() } type Event interface { Name() string Data() any } type eventBus struct { topics map[string]gubgub.Topic[Event] } func NewSyncEventBus() *eventBus { return &eventBus{ topics: make(map[string]gubgub.Topic[Event]), } } func (eb *eventBus) Emit(e Event) error { topic, ok := eb.topics[e.Name()] if !ok { return nil } err := topic.Publish(e) if err != nil { return fmt.Errorf("emit event: %w", err) } return nil } func (eb *eventBus) Listen(name string, handler func(Event)) error { topic, ok := eb.topics[name] if !ok { topic = gubgub.NewSyncTopic[Event]() eb.topics[name] = topic } err := topic.Subscribe(gubgub.Forever(handler)) if err != nil { return fmt.Errorf("listen for event: %w", err) } return nil }