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 () Close ()
} }
// Broadcaster manages event listeners // Broadcaster manages event listeners.
type Broadcaster struct { type Broadcaster[L any] struct {
lastID int lastID int
listeners map[int] func () listeners map[int] L
} }
// Connect adds a new listener to the broadcaster and returns a corresponding // Connect adds a new listener to the broadcaster and returns a corresponding
// cookie. // cookie.
func (broadcaster *Broadcaster) Connect (listener func ()) Cookie { func (broadcaster *Broadcaster[L]) Connect (listener L) Cookie {
if listener == nil { return nil } broadcaster.ensure()
if broadcaster.listeners == nil {
broadcaster.listeners = make(map[int] func ())
}
cookie := broadcaster.newCookie() cookie := broadcaster.newCookie()
broadcaster.listeners[cookie.id] = listener broadcaster.listeners[cookie.id] = listener
return cookie return cookie
} }
// Broadcast runs all event listeners at once. // Listeners returns a map of all connected listeners.
func (broadcaster *Broadcaster) Broadcast () { func (broadcaster *Broadcaster[L]) Listeners () map[int] L {
for _, listener := range broadcaster.listeners { broadcaster.ensure()
listener() return broadcaster.listeners
}
} }
func (broadcaster *Broadcaster) newCookie () cookie { func (broadcaster *Broadcaster[L]) newCookie () cookie[L] {
broadcaster.lastID ++ broadcaster.lastID ++
return cookie { return cookie[L] {
id: broadcaster.lastID, id: broadcaster.lastID,
broadcaster: broadcaster, broadcaster: broadcaster,
} }
} }
type cookie struct { func (broadcaster *Broadcaster[L]) ensure () {
id int if broadcaster.listeners == nil {
broadcaster *Broadcaster 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) 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 () {
}