v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/broadcast/evbus/evbus.go (about) 1 package evbus 2 3 import ( 4 "strconv" 5 "sync" 6 "sync/atomic" 7 8 "v8.run/go/exp/broadcast" 9 ) 10 11 var evbus_map sync.Map 12 13 func Publish[T any](topic string, v T) { 14 t, ok := evbus_map.Load(topic) 15 if !ok || t == nil { 16 t, _ = evbus_map.LoadOrStore(topic, broadcast.NewTopic[any]()) 17 } 18 t.(*broadcast.Topic[any]).Broadcast(v) 19 } 20 21 type Subscription struct { 22 topic string 23 s *broadcast.Subscription[any] 24 stop atomic.Uint32 25 } 26 27 func Subscribe[T any](topic string, fn func(v T) (Unsubscribe bool)) *Subscription { 28 t, ok := evbus_map.Load(topic) 29 if !ok || t == nil { 30 t, _ = evbus_map.LoadOrStore(topic, broadcast.NewTopic[any]()) 31 } 32 var ss Subscription 33 ss.topic = topic 34 35 ss.s = t.(*broadcast.Topic[any]).Subscribe(func(v any) { 36 if ss.stop.Load() == 1 { 37 return 38 } 39 40 if val, ok := v.(T); ok { 41 unsub := fn(val) 42 if unsub { 43 ss.Unsubscribe() 44 } 45 } 46 }) 47 48 return &ss 49 } 50 51 func (ss *Subscription) Unsubscribe() { 52 if ss.stop.CompareAndSwap(0, 1) { 53 go ss.s.Unsubscribe() 54 } 55 } 56 57 func (ss *Subscription) String() string { 58 return "<Subscription " + strconv.Quote(ss.topic) + " >" 59 }