| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 | 
							- /*
 
-  * Public Domain Software
 
-  *
 
-  * I (Matthias Ladkau) am the author of the source code in this file.
 
-  * I have placed the source code in this file in the public domain.
 
-  *
 
-  * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
 
-  */
 
- /*
 
- Package flowutil contains utilities to manage control flow.
 
- */
 
- package flowutil
 
- import "sync"
 
- /*
 
- EventPump implements the observer pattern. Observers can subscribe to receive
 
- notifications on certain events. Observed objects can send notifications.
 
- */
 
- type EventPump struct {
 
- 	eventsObservers     map[string]map[interface{}][]EventCallback
 
- 	eventsObserversLock *sync.Mutex
 
- }
 
- /*
 
- EventCallback is the callback function which is called when an event was observed.
 
- */
 
- type EventCallback func(event string, eventSource interface{})
 
- /*
 
- NewEventPump creates a new event pump.
 
- */
 
- func NewEventPump() *EventPump {
 
- 	return &EventPump{make(map[string]map[interface{}][]EventCallback), &sync.Mutex{}}
 
- }
 
- /*
 
- AddObserver adds a new observer to the event pump. An observer can subscribe to
 
- a given event from a given event source. If the event is an empty string then
 
- the observer subscribes to all events from the event source. If the
 
- eventSource is nil then the observer subscribes to all event sources.
 
- */
 
- func (ep *EventPump) AddObserver(event string, eventSource interface{}, callback EventCallback) {
 
- 	// Ignore requests with non-existent callbacks
 
- 	if callback == nil {
 
- 		return
 
- 	}
 
- 	ep.eventsObserversLock.Lock()
 
- 	defer ep.eventsObserversLock.Unlock()
 
- 	sources, ok := ep.eventsObservers[event]
 
- 	if !ok {
 
- 		sources = make(map[interface{}][]EventCallback)
 
- 		ep.eventsObservers[event] = sources
 
- 	}
 
- 	callbacks, ok := sources[eventSource]
 
- 	if !ok {
 
- 		callbacks = []EventCallback{callback}
 
- 		sources[eventSource] = callbacks
 
- 	} else {
 
- 		sources[eventSource] = append(callbacks, callback)
 
- 	}
 
- }
 
- /*
 
- PostEvent posts an event to this event pump from a given event source.
 
- */
 
- func (ep *EventPump) PostEvent(event string, eventSource interface{}) {
 
- 	if event == "" || eventSource == nil {
 
- 		panic("Posting an event requires the event and its source")
 
- 	}
 
- 	ep.eventsObserversLock.Lock()
 
- 	defer ep.eventsObserversLock.Unlock()
 
- 	postEvent := func(event string, eventSource interface{}) {
 
- 		if sources, ok := ep.eventsObservers[event]; ok {
 
- 			for source, callbacks := range sources {
 
- 				if source == eventSource || source == nil {
 
- 					for _, callback := range callbacks {
 
- 						ep.eventsObserversLock.Unlock()
 
- 						callback(event, eventSource)
 
- 						ep.eventsObserversLock.Lock()
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- 	postEvent(event, eventSource)
 
- 	postEvent("", eventSource)
 
- }
 
- /*
 
- RemoveObservers removes observers from the event pump. If the event is an
 
- empty string then the observer is removed from all events. If the
 
- eventSource is nil then all observers of the event are dropped.
 
- */
 
- func (ep *EventPump) RemoveObservers(event string, eventSource interface{}) {
 
- 	ep.eventsObserversLock.Lock()
 
- 	defer ep.eventsObserversLock.Unlock()
 
- 	// Clear everything
 
- 	if event == "" && eventSource == nil {
 
- 		ep.eventsObservers = make(map[string]map[interface{}][]EventCallback)
 
- 	} else if eventSource == nil {
 
- 		delete(ep.eventsObservers, event)
 
- 	} else if event == "" {
 
- 		for _, sources := range ep.eventsObservers {
 
- 			delete(sources, eventSource)
 
- 		}
 
- 	} else {
 
- 		if sources, ok := ep.eventsObservers[event]; ok {
 
- 			delete(sources, eventSource)
 
- 		}
 
- 	}
 
- }
 
 
  |