2022-09-25 11:42:36 -04:00
|
|
|
package bus
|
|
|
|
|
2022-10-25 00:16:29 -04:00
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
)
|
2022-09-25 11:42:36 -04:00
|
|
|
|
2022-10-25 00:16:29 -04:00
|
|
|
type (
|
|
|
|
Event struct {
|
|
|
|
EvType string
|
|
|
|
Data interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
listeners []chan<- Event
|
|
|
|
|
|
|
|
Bus struct {
|
|
|
|
sync.RWMutex
|
|
|
|
subs map[string]listeners
|
|
|
|
}
|
|
|
|
)
|
2022-09-25 11:42:36 -04:00
|
|
|
|
|
|
|
func New() *Bus {
|
2022-10-25 00:16:29 -04:00
|
|
|
bus := &Bus{
|
|
|
|
subs: make(map[string]listeners),
|
|
|
|
}
|
2022-09-25 11:42:36 -04:00
|
|
|
|
|
|
|
return bus
|
2022-10-25 00:16:29 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bus) Sub(topic string, ch chan<- Event) {
|
|
|
|
b.Lock()
|
|
|
|
defer b.Unlock()
|
|
|
|
|
|
|
|
if prev, ok := b.subs[topic]; ok {
|
|
|
|
b.subs[topic] = append(prev, ch)
|
|
|
|
} else {
|
|
|
|
b.subs[topic] = append(listeners{}, ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bus) Unsub(topic string, ch chan<- Event) {
|
|
|
|
b.Lock()
|
|
|
|
defer b.Unlock()
|
|
|
|
|
|
|
|
for i, v := range b.subs[topic] {
|
|
|
|
if v == ch {
|
|
|
|
// we don't care about order, replace and reslice
|
|
|
|
b.subs[topic][i] = b.subs[topic][len(b.subs[topic])-1]
|
|
|
|
b.subs[topic] = b.subs[topic][:len(b.subs[topic])-1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bus) Pub(topic string, data interface{}) {
|
|
|
|
b.RLock()
|
|
|
|
defer b.RUnlock()
|
|
|
|
|
|
|
|
tc, ok := b.subs[topic]
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ch := range tc {
|
|
|
|
ch <- Event{EvType: topic, Data: data}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bus) Shutdown() {
|
|
|
|
for _, v := range b.subs {
|
|
|
|
for _, c := range v {
|
|
|
|
close(c)
|
|
|
|
}
|
|
|
|
}
|
2022-09-25 11:42:36 -04:00
|
|
|
}
|