|
|
@@ -4,31 +4,30 @@
|
|
|
|
|
|
package core
|
|
|
|
|
|
-// Dispatcher implements an event dispatcher
|
|
|
-type Dispatcher struct {
|
|
|
- evmap map[string][]subscription // maps event name to subcriptions list
|
|
|
- cancel bool // flag informing cancelled dispatch
|
|
|
-}
|
|
|
-
|
|
|
-// IDispatcher is the interface for dispatchers
|
|
|
+// IDispatcher is the interface for event dispatchers.
|
|
|
type IDispatcher interface {
|
|
|
Subscribe(evname string, cb Callback)
|
|
|
SubscribeID(evname string, id interface{}, cb Callback)
|
|
|
UnsubscribeID(evname string, id interface{}) int
|
|
|
- Dispatch(evname string, ev interface{}) bool
|
|
|
- ClearSubscriptions()
|
|
|
- CancelDispatch()
|
|
|
+ UnsubscribeAllID(id interface{}) int
|
|
|
+ Dispatch(evname string, ev interface{}) int
|
|
|
+}
|
|
|
+
|
|
|
+// Dispatcher implements an event dispatcher.
|
|
|
+type Dispatcher struct {
|
|
|
+ evmap map[string][]subscription // Map of event names to subscription lists
|
|
|
}
|
|
|
|
|
|
-// Callback is the type for the Dispatcher callbacks functions
|
|
|
+// Callback is the type for Dispatcher callback functions.
|
|
|
type Callback func(string, interface{})
|
|
|
|
|
|
+// subscription links a Callback with a user-provided unique id.
|
|
|
type subscription struct {
|
|
|
id interface{}
|
|
|
- cb func(string, interface{})
|
|
|
+ cb Callback
|
|
|
}
|
|
|
|
|
|
-// NewDispatcher creates and returns a new Event Dispatcher
|
|
|
+// NewDispatcher creates and returns a new event dispatcher.
|
|
|
func NewDispatcher() *Dispatcher {
|
|
|
|
|
|
d := new(Dispatcher)
|
|
|
@@ -36,97 +35,78 @@ func NewDispatcher() *Dispatcher {
|
|
|
return d
|
|
|
}
|
|
|
|
|
|
-// Initialize initializes this event dispatcher.
|
|
|
-// It is normally used by other types which embed an event dispatcher
|
|
|
+// Initialize initializes the event dispatcher.
|
|
|
+// It is normally used by other types which embed a dispatcher.
|
|
|
func (d *Dispatcher) Initialize() {
|
|
|
|
|
|
d.evmap = make(map[string][]subscription)
|
|
|
}
|
|
|
|
|
|
-// Subscribe subscribes to receive events with the given name.
|
|
|
-// If it is necessary to unsubscribe the event, the function SubscribeID should be used.
|
|
|
+// Subscribe subscribes a callback to events with the given name.
|
|
|
+// If it is necessary to unsubscribe later, SubscribeID should be used instead.
|
|
|
func (d *Dispatcher) Subscribe(evname string, cb Callback) {
|
|
|
|
|
|
- d.SubscribeID(evname, nil, cb)
|
|
|
+ d.evmap[evname] = append(d.evmap[evname], subscription{nil, cb})
|
|
|
}
|
|
|
|
|
|
-// SubscribeID subscribes to receive events with the given name.
|
|
|
-// The function accepts a unique id to be use to unsubscribe this event
|
|
|
+// SubscribeID subscribes a callback to events events with the given name.
|
|
|
+// The user-provided unique id can be used to unsubscribe via UnsubscribeID.
|
|
|
func (d *Dispatcher) SubscribeID(evname string, id interface{}, cb Callback) {
|
|
|
|
|
|
d.evmap[evname] = append(d.evmap[evname], subscription{id, cb})
|
|
|
}
|
|
|
|
|
|
-// UnsubscribeID unsubscribes from the specified event and subscription id
|
|
|
-// Returns the number of subscriptions found.
|
|
|
+// UnsubscribeID removes all subscribed callbacks with the specified unique id from the specified event.
|
|
|
+// Returns the number of subscriptions removed.
|
|
|
func (d *Dispatcher) UnsubscribeID(evname string, id interface{}) int {
|
|
|
|
|
|
// Get list of subscribers for this event
|
|
|
- // If not found, nothing to do
|
|
|
- subs, ok := d.evmap[evname]
|
|
|
- if !ok {
|
|
|
+ subs := d.evmap[evname]
|
|
|
+ if len(subs) == 0 {
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
- // Remove all subscribers with the specified id for this event
|
|
|
- found := 0
|
|
|
- pos := 0
|
|
|
- for pos < len(subs) {
|
|
|
- if subs[pos].id == id {
|
|
|
- copy(subs[pos:], subs[pos+1:])
|
|
|
- subs[len(subs)-1] = subscription{}
|
|
|
- subs = subs[:len(subs)-1]
|
|
|
- found++
|
|
|
+ // Remove all subscribers of the specified event with the specified id, counting how many were removed
|
|
|
+ rm := 0
|
|
|
+ i := 0
|
|
|
+ for _, s := range subs {
|
|
|
+ if s.id == id {
|
|
|
+ rm++
|
|
|
} else {
|
|
|
- pos++
|
|
|
+ subs[i] = s
|
|
|
+ i++
|
|
|
}
|
|
|
}
|
|
|
- d.evmap[evname] = subs
|
|
|
- return found
|
|
|
+ d.evmap[evname] = subs[:i]
|
|
|
+ return rm
|
|
|
}
|
|
|
|
|
|
-// UnsubscribeAllID unsubscribes from all events with the specified subscription id.
|
|
|
-// Returns the number of subscriptions found.
|
|
|
+// UnsubscribeAllID removes all subscribed callbacks with the specified unique id from all events.
|
|
|
+// Returns the number of subscriptions removed.
|
|
|
func (d *Dispatcher) UnsubscribeAllID(id interface{}) int {
|
|
|
|
|
|
+ // Remove all subscribers with the specified id (for all events), counting how many were removed
|
|
|
total := 0
|
|
|
for evname := range d.evmap {
|
|
|
- found := d.UnsubscribeID(evname, id)
|
|
|
- total += found
|
|
|
+ total += d.UnsubscribeID(evname, id)
|
|
|
}
|
|
|
return total
|
|
|
}
|
|
|
|
|
|
-// Dispatch dispatch the specified event and data to all registered subscribers.
|
|
|
-// The function returns true if the propagation was cancelled by a subscriber.
|
|
|
-func (d *Dispatcher) Dispatch(evname string, ev interface{}) bool {
|
|
|
+// Dispatch dispatches the specified event to all registered subscribers.
|
|
|
+// The function returns the number of subscribers to which the event was dispatched.
|
|
|
+func (d *Dispatcher) Dispatch(evname string, ev interface{}) int {
|
|
|
|
|
|
// Get list of subscribers for this event
|
|
|
subs := d.evmap[evname]
|
|
|
- if subs == nil {
|
|
|
- return false
|
|
|
+ nsubs := len(subs)
|
|
|
+ if nsubs == 0 {
|
|
|
+ return 0
|
|
|
}
|
|
|
|
|
|
- // Dispatch to all subscribers
|
|
|
- d.cancel = false
|
|
|
- for i := 0; i < len(subs); i++ {
|
|
|
- subs[i].cb(evname, ev)
|
|
|
- if d.cancel {
|
|
|
- break
|
|
|
- }
|
|
|
+ // Dispatch event to all subscribers
|
|
|
+ for _, s := range subs {
|
|
|
+ s.cb(evname, ev)
|
|
|
}
|
|
|
- return d.cancel
|
|
|
-}
|
|
|
-
|
|
|
-// ClearSubscriptions clear all subscriptions from this dispatcher
|
|
|
-func (d *Dispatcher) ClearSubscriptions() {
|
|
|
-
|
|
|
- d.evmap = make(map[string][]subscription)
|
|
|
-}
|
|
|
-
|
|
|
-// CancelDispatch cancels the propagation of the current event.
|
|
|
-// No more subscribers will be called for this event dispatch.
|
|
|
-func (d *Dispatcher) CancelDispatch() {
|
|
|
-
|
|
|
- d.cancel = true
|
|
|
+ return nsubs
|
|
|
}
|