diff --git a/utils/reactivevalue.go b/utils/reactivevalue.go new file mode 100644 index 0000000..29fcff7 --- /dev/null +++ b/utils/reactivevalue.go @@ -0,0 +1,36 @@ +package utils + +type ReactiveValue[T any] struct { + V T + subscribers []chan *T +} + +func NewReactiveValue[T any](value T) *ReactiveValue[T] { + return &ReactiveValue[T]{ + V: value, + subscribers: make([]chan *T, 0), + } +} + +func (rv *ReactiveValue[T]) Set(value T) { + rv.V = value + for _, subscriber := range rv.subscribers { + subscriber <- &value + } +} + +func (rv *ReactiveValue[T]) Subscribe() chan *T { + subscriber := make(chan *T) + rv.subscribers = append(rv.subscribers, subscriber) + return subscriber +} + +func (rv *ReactiveValue[T]) Unsubscribe(subscriber chan *T) { + for i, s := range rv.subscribers { + if s == subscriber { + rv.subscribers = append(rv.subscribers[:i], rv.subscribers[i+1:]...) + close(subscriber) + return + } + } +}