// Package hub provides a simple event dispatcher for publish/subscribe pattern.
package hub import type Kind int // Event is an interface for published events. type Event interface { Kind() Kind } // Hub is an event dispatcher, publishes events to the subscribers // which are subscribed for a specific event type. // Optimized for publish calls. // The handlers may be called in order different than they are registered. type Hub struct { subscribers map[Kind][]handler m sync.RWMutex seq uint64 } type handler struct { f func(Event) id uint64 } // Subscribe registers f for the event of a specific kind. func ( *Hub) ( Kind, func(Event)) ( func()) { var bool .m.Lock() .seq++ := .seq if .subscribers == nil { .subscribers = make(map[Kind][]handler) } .subscribers[] = append(.subscribers[], handler{id: , f: }) .m.Unlock() return func() { .m.Lock() if { .m.Unlock() return } = true := .subscribers[] for , := range { if .id == { [], .subscribers[] = [len()-1], [:len()-1] break } } if len() == 0 { delete(.subscribers, ) } .m.Unlock() } } // Publish an event to the subscribers. func ( *Hub) ( Event) { .m.RLock() if , := .subscribers[.Kind()]; { for , := range { .f() } } .m.RUnlock() } // DefaultHub is the default Hub used by Publish and Subscribe. var DefaultHub Hub // Subscribe registers f for the event of a specific kind in the DefaultHub. func ( Kind, func(Event)) ( func()) { return DefaultHub.Subscribe(, ) } // Publish an event to the subscribers in DefaultHub. func ( Event) { DefaultHub.Publish() }