package bus import ( "container/list" "lmika.dev/lmika/hugo-cms/models" ) type Bus struct { subs *list.List eventQueue chan models.Event } func New() *Bus { return &Bus{ subs: list.New(), eventQueue: make(chan models.Event, 20), } } func (b *Bus) Fire(event models.Event) { b.eventQueue <- event } func (b *Bus) Start() { go func() { for e := range b.eventQueue { switch e.Type { case models.EventTypeSubscribe: retChan := e.Data.(chan *models.Sub) newSub := &models.Sub{C: make(chan models.Event, 1)} newSub.Elem = b.subs.PushBack(newSub) retChan <- newSub case models.EventTypeUnsubscribe: sub := e.Data.(*models.Sub) close(sub.C) b.subs.Remove(sub.Elem) default: for f := b.subs.Front(); f != nil; f = f.Next() { sub := f.Value.(*models.Sub) select { case sub.C <- e: default: } } } } }() } func (b *Bus) Stop() { close(b.eventQueue) } func (b *Bus) Subscribe() *models.Sub { resChan := make(chan *models.Sub) b.eventQueue <- models.Event{Type: models.EventTypeSubscribe, Data: resChan} return <-resChan } func (b *Bus) Unsubscribe(sub *models.Sub) { b.eventQueue <- models.Event{Type: models.EventTypeUnsubscribe, Data: sub} }