tomo/event/event.go

86 lines
2.0 KiB
Go
Raw Permalink Normal View History

2023-06-30 23:40:45 +00:00
// Package event provides a system for broadcasting events to multiple event
// handlers.
2023-06-30 20:38:51 +00:00
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 ()
}
2023-07-01 23:00:26 +00:00
// Broadcaster manages event listeners.
type Broadcaster[L any] struct {
2023-06-30 20:38:51 +00:00
lastID int
2023-07-01 23:00:26 +00:00
listeners map[int] L
2023-06-30 20:38:51 +00:00
}
// Connect adds a new listener to the broadcaster and returns a corresponding
// cookie.
2023-07-01 23:00:26 +00:00
func (broadcaster *Broadcaster[L]) Connect (listener L) Cookie {
broadcaster.ensure()
2023-06-30 20:38:51 +00:00
cookie := broadcaster.newCookie()
broadcaster.listeners[cookie.id] = listener
return cookie
}
2023-07-01 23:00:26 +00:00
// Listeners returns a map of all connected listeners.
func (broadcaster *Broadcaster[L]) Listeners () map[int] L {
broadcaster.ensure()
return broadcaster.listeners
2023-06-30 20:38:51 +00:00
}
2023-07-01 23:00:26 +00:00
func (broadcaster *Broadcaster[L]) newCookie () cookie[L] {
2023-06-30 20:38:51 +00:00
broadcaster.lastID ++
2023-07-01 23:00:26 +00:00
return cookie[L] {
2023-06-30 20:38:51 +00:00
id: broadcaster.lastID,
broadcaster: broadcaster,
}
}
2023-07-01 23:00:26 +00:00
func (broadcaster *Broadcaster[L]) ensure () {
if broadcaster.listeners == nil {
broadcaster.listeners = make(map[int] L)
}
}
2023-08-09 16:08:17 +00:00
// NoCookie is a cookie that does nothing when closed.
type NoCookie struct { }
func (NoCookie) Close () { }
2023-07-01 23:00:26 +00:00
type cookie[L any] struct {
2023-06-30 20:38:51 +00:00
id int
2023-07-01 23:00:26 +00:00
broadcaster *Broadcaster[L]
2023-06-30 20:38:51 +00:00
}
2023-07-01 23:00:26 +00:00
func (cookie cookie[L]) Close () {
2023-06-30 20:38:51 +00:00
delete(cookie.broadcaster.listeners, cookie.id)
}
2023-07-01 23:00:26 +00:00
// FuncBroadcaster is a broadcaster that manages functions with no arguments.
2023-07-01 23:08:39 +00:00
type FuncBroadcaster struct {
Broadcaster[func ()]
}
2023-07-01 23:00:26 +00:00
// Broadcast calls all connected listener funcs.
func (broadcaster *FuncBroadcaster) Broadcast () {
for _, listener := range broadcaster.Listeners() {
listener()
}
2023-07-01 23:00:26 +00:00
}
2023-08-08 01:56:28 +00:00
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()
}
}