85 lines
1.4 KiB
Go
85 lines
1.4 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{}) {
|
|
// TODO: make thread safe
|
|
t, hasTopic := d.topics[event]
|
|
if !hasTopic {
|
|
t = &topic{}
|
|
d.topics[event] = t
|
|
}
|
|
|
|
sub, err := newSubscriptionFromFunc(receiver)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
t.addSubscriber(sub)
|
|
}
|
|
|
|
func (d *Bus) Fire(event string, args ...interface{}) {
|
|
_ = d.TryFire(event, args...)
|
|
}
|
|
|
|
func (d *Bus) TryFire(event string, args ...interface{}) error {
|
|
// TODO: make thead safe
|
|
topic, hasTopic := d.topics[event]
|
|
if !hasTopic {
|
|
return nil
|
|
}
|
|
|
|
preparedArgs := prepareArgs(args)
|
|
|
|
var errs []error
|
|
|
|
for sub := topic.head; sub != nil; sub = sub.next {
|
|
err := sub.handler.invoke(preparedArgs)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
|
|
switch len(errs) {
|
|
case 0:
|
|
return nil
|
|
case 1:
|
|
return errs[0]
|
|
}
|
|
return HandlerError{topic: event, errs: errs}
|
|
}
|
|
|
|
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
|
|
}
|