Make broadcaster generic

This commit is contained in:
Sasha Koshka 2023-07-01 19:00:26 -04:00
parent b00a7302b4
commit 3e92de7485
1 changed files with 29 additions and 20 deletions

View File

@ -9,46 +9,55 @@ type Cookie interface {
Close ()
}
// Broadcaster manages event listeners
type Broadcaster struct {
// Broadcaster manages event listeners.
type Broadcaster[L any] struct {
lastID int
listeners map[int] func ()
listeners map[int] L
}
// Connect adds a new listener to the broadcaster and returns a corresponding
// cookie.
func (broadcaster *Broadcaster) Connect (listener func ()) Cookie {
if listener == nil { return nil }
if broadcaster.listeners == nil {
broadcaster.listeners = make(map[int] func ())
}
func (broadcaster *Broadcaster[L]) Connect (listener L) Cookie {
broadcaster.ensure()
cookie := broadcaster.newCookie()
broadcaster.listeners[cookie.id] = listener
return cookie
}
// Broadcast runs all event listeners at once.
func (broadcaster *Broadcaster) Broadcast () {
for _, listener := range broadcaster.listeners {
listener()
}
// Listeners returns a map of all connected listeners.
func (broadcaster *Broadcaster[L]) Listeners () map[int] L {
broadcaster.ensure()
return broadcaster.listeners
}
func (broadcaster *Broadcaster) newCookie () cookie {
func (broadcaster *Broadcaster[L]) newCookie () cookie[L] {
broadcaster.lastID ++
return cookie {
return cookie[L] {
id: broadcaster.lastID,
broadcaster: broadcaster,
}
}
type cookie struct {
id int
broadcaster *Broadcaster
func (broadcaster *Broadcaster[L]) ensure () {
if broadcaster.listeners == nil {
broadcaster.listeners = make(map[int] L)
}
}
func (cookie cookie) Close () {
type cookie[L any] struct {
id int
broadcaster *Broadcaster[L]
}
func (cookie cookie[L]) Close () {
delete(cookie.broadcaster.listeners, cookie.id)
}
// FuncBroadcaster is a broadcaster that manages functions with no arguments.
type FuncBroadcaster Broadcaster[func ()]
// Broadcast calls all connected listener funcs.
func (broadcaster *FuncBroadcaster) Broadcast () {
}