2022-11-30 18:15:47 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import "git.sr.ht/~hamcha/containers"
|
|
|
|
|
|
|
|
type PubSub[T Comparable] struct {
|
2022-12-03 23:04:15 +00:00
|
|
|
subscribers *containers.SyncSlice[T]
|
2022-11-30 18:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewPubSub[T Comparable]() *PubSub[T] {
|
|
|
|
return &PubSub[T]{
|
2022-12-03 23:04:15 +00:00
|
|
|
subscribers: containers.NewSyncSlice[T](),
|
2022-11-30 18:15:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PubSub[T]) Subscribe(handler T) {
|
2022-12-03 23:04:15 +00:00
|
|
|
p.subscribers.Push(handler)
|
2022-11-30 18:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PubSub[T]) Unsubscribe(handler T) {
|
2022-12-03 23:04:15 +00:00
|
|
|
arr := p.subscribers.Copy()
|
2022-11-30 18:15:47 +00:00
|
|
|
// Use slice trick to in-place remove entry if found
|
|
|
|
for index := range arr {
|
|
|
|
if arr[index].Equals(handler) {
|
|
|
|
arr[index] = arr[len(arr)-1]
|
|
|
|
p.subscribers.Set(arr[:len(arr)-1])
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PubSub[T]) Subscribers() []T {
|
2022-12-03 23:04:15 +00:00
|
|
|
return p.subscribers.Copy()
|
2022-11-30 18:15:47 +00:00
|
|
|
}
|
2022-12-03 15:16:59 +00:00
|
|
|
|
|
|
|
func (p *PubSub[T]) Copy(other *PubSub[T]) {
|
|
|
|
for _, subscriber := range other.Subscribers() {
|
|
|
|
p.Subscribe(subscriber)
|
|
|
|
}
|
|
|
|
}
|