package app import "sync" // Topic is a generic pub/sub for broadcasting updates. type Topic[T any] struct { c []chan *T mu sync.Mutex } // Watch subscribes a channel to receive updates. func (t *Topic[T]) Watch(c chan *T) { t.mu.Lock() defer t.mu.Unlock() t.c = append(t.c, c) } // Send broadcasts to all subscribers. func (t *Topic[T]) Send(b *T) { t.mu.Lock() defer t.mu.Unlock() for i := 0; i < len(t.c); i++ { select { case t.c[i] <- b: default: close(t.c[i]) t.c[i] = t.c[len(t.c)-1] t.c = t.c[:len(t.c)-1] } } } // Close closes all subscriber channels. func (t *Topic[T]) Close() { t.mu.Lock() defer t.mu.Unlock() for _, c := range t.c { close(c) } t.c = t.c[:0] } // Merge represents a map merge event (two maps becoming one). type Merge struct { From, To int Shift Coord }