Daniel Salvadori преди 6 години
родител
ревизия
b1251f86f4
променени са 1 файла, в които са добавени 47 реда и са изтрити 67 реда
  1. 47 67
      core/dispatcher.go

+ 47 - 67
core/dispatcher.go

@@ -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
 }