// Package event provides a system for broadcasting events to multiple event // handlers. package event // A cookie is returned when you add an event handler so you can remove it // later if you so choose. type Cookie interface { // Close removes the event handler this cookie is for. Close () } // Broadcaster manages event listeners. type Broadcaster[L any] struct { lastID int listeners map[int] L } // Connect adds a new listener to the broadcaster and returns a corresponding // cookie. func (broadcaster *Broadcaster[L]) Connect (listener L) Cookie { broadcaster.ensure() cookie := broadcaster.newCookie() broadcaster.listeners[cookie.id] = listener return cookie } // Listeners returns a map of all connected listeners. func (broadcaster *Broadcaster[L]) Listeners () map[int] L { broadcaster.ensure() return broadcaster.listeners } func (broadcaster *Broadcaster[L]) newCookie () cookie[L] { broadcaster.lastID ++ return cookie[L] { id: broadcaster.lastID, broadcaster: broadcaster, } } func (broadcaster *Broadcaster[L]) ensure () { if broadcaster.listeners == nil { broadcaster.listeners = make(map[int] L) } } // NoCookie is a cookie that does nothing when closed. type NoCookie struct { } func (NoCookie) 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 struct { Broadcaster[func ()] } // Broadcast calls all connected listener funcs. func (broadcaster *FuncBroadcaster) Broadcast () { for _, listener := range broadcaster.Listeners() { listener() } } type multiCookie []Cookie // MultiCookie creates a single cookie that, when closed, closes a list of other // cookies. func MultiCookie (cookies ...Cookie) Cookie { return multiCookie(cookies) } func (cookies multiCookie) Close () { for _, cookie := range cookies { cookie.Close() } }