events/bus.go

68 lines
1.2 KiB
Go

package events
type Bus struct {
topics map[string]*topic
}
func New() *Bus {
return &Bus{topics: make(map[string]*topic)}
}
func (d *Bus) On(event string, receiver interface{}) error {
// TODO: make thread safe
t, hasTopic := d.topics[event]
if !hasTopic {
t = &topic{}
d.topics[event] = t
}
sub, err := newSubscriptionFromFunc(receiver)
if err != nil {
return err
}
t.addSubscriber(sub)
return nil
}
func (d *Bus) Fire(event string, args ...interface{}) {
// TODO: make thead safe
topic, hasTopic := d.topics[event]
if !hasTopic {
return
}
preparedArgs := prepareArgs(args)
for sub := topic.head; sub != nil; sub = sub.next {
sub.handler.invoke(preparedArgs)
}
}
type topic struct {
head *subscription
tail *subscription
}
func (t *topic) addSubscriber(sub *subscription) {
if t.head == nil {
t.head = sub
}
if t.tail != nil {
t.tail.next = sub
}
t.tail = sub
}
type subscription struct {
handler receiptHandler
next *subscription
}
func newSubscriptionFromFunc(fn interface{}) (*subscription, error) {
handler, err := newReceiptHandler(fn)
if err != nil {
return nil, err
}
return &subscription{handler: handler, next: nil}, nil
}