<filename>python/soma_workflow/observer.py
# -*- coding: utf-8 -*-

from __future__ import print_function
from __future__ import absolute_import
import weakref


class Observable(object):

    def __init__(self):
        # A WeakKeyDictionary is one where, if the object used as the key
        # gets deleted, automatically removes that key from the
        # dictionary.  Thus, any Observers which get deleted will be
        # automatically removed from the observers dictionary, thus having
        # two effects:
        # We won't have references to zombie objects in the dictionary, and
        # We won't have zombie objects, because the reference in this
        # dictionary won't stay around, and so won't keep the deleted object
        # alive.
        self._observers = weakref.WeakKeyDictionary()

    #
    # Add an observer to this Observable's notification list.
    # @param observer The Observer to add.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # "update" method.
    # @param events The events the Observer is interested in being
    # notified about.  None means all events.

    def addObserver(self, observer, cbname=None, events=None):
        if cbname is None:
            cbname = "update"
        if events is not None and type(events) not in (tuple, list):
            events = (events,)
        self._observers[observer] = (cbname, events)

    #
    # Remove an observer from this Observable's list of observers.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the notification list.
    # @param observer the Observer to remove.

    def removeObserver(self, observer):
        if observer in self._observers:
            del self._observers[observer]

    #
    # Notify all currently-registered Observers.
    # Each observer must have an 'update' method, which should take
    # three parameters (in addition to self): the Observable, an event,
    # and a message.
    # This method will be
    # called if the event is one that the Observer is interested in,
    # or if event is 'None', or if the Observer is interested in all
    # events (it was registered with an event list of 'None').
    # @param event The event to notify the Observers about.  None
    # means no specific event.
    # @param msg A reference to any data object that should be passed
    # to the Observers, or None.

    def notifyObservers(self, event=None, msg=None):
        for observer, data in self._observers.items():
            # print("data is", data)
            cbname, events = data
            # print("cbname is", cbname)
            # print("events is", events)
            # print("event is", event)
            if events is None or event is None or event in events:
                # print("observer is " + repr(observer))
                cb = getattr(observer, cbname, None)
                if cb is None:
                    raise NotImplementedError(
                        "Observer has no %s method." % cbname)
                cb(self, event, msg)


#
# The abstract Observer Class
# This class is a mix-in to add Observable registration methods to
# a concrete Observer class.  It is not strictly required.
#

class Observer(object):

    #
    # @param observable The Observable to observe.
    # @param The events this Observer is interested in being
    # notified about.  This should be a tuple or list of events.

    def __init__(self, observable=None, cbname=None, events=None):
        if (observable is not None):
            observable.addObserver(self, cbname, events)

    #
    # Inform an Observable that you would like to be notified when
    # an interesting event occurs in the Observable.
    # @param observable The Observable this Observer would like
    # to observe.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # "update" method.
    # @param events A tuple or list of events this Observer would like
    # to be notified of by the Observer, or None if it would like to
    # be notified of all events.

    def subscribeToObservable(self, observable, cbname=None, events=None):
        assert observable is not None, "Observable is None"
        observable.addObserver(self, cbname, events)

    #
    # Inform an observable that this Observer is no longer interested in it.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the Observable's notification list.
    # Use this function when you want to unsubscribe an Observer
    # without deleting it.
    # @param observable The Observable that this Observer no longer wants
    # to observe.

    def unsubscribeToObservable(self, observable):
        assert observable is not None, "Observable is None"
        observable.removeObserver(self)

<filename>python/soma_workflow/observer.py
# -*- coding: utf-8 -*-

from __future__ import print_function
from __future__ import absolute_import
import weakref


class Observable(object):

    def __init__(self):
        # A WeakKeyDictionary is one where, if the object used as the key
        # gets deleted, automatically removes that key from the
        # dictionary.  Thus, any Observers which get deleted will be
        # automatically removed from the observers dictionary, thus having
        # two effects:
        # We won't have references to zombie objects in the dictionary, and
        # We won't have zombie objects, because the reference in this
        # dictionary won't stay around, and so won't keep the deleted object
        # alive.
        self._observers = weakref.WeakKeyDictionary()

    #
    # Add an observer to this Observable's notification list.
    # @param observer The Observer to add.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # "update" method.
    # @param events The events the Observer is interested in being
    # notified about.  None means all events.

    def addObserver(self, observer, cbname=None, events=None):
        if cbname is None:
            cbname = "update"
        if events is not None and type(events) not in (tuple, list):
            events = (events,)
        self._observers[observer] = (cbname, events)

    #
    # Remove an observer from this Observable's list of observers.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the notification list.
    # @param observer the Observer to remove.

    def removeObserver(self, observer):
        if observer in self._observers:
            del self._observers[observer]

    #
    # Notify all currently-registered Observers.
    # Each observer must have an 'update' method, which should take
    # three parameters (in addition to self): the Observable, an event,
    # and a message.
    # This method will be
    # called if the event is one that the Observer is interested in,
    # or if event is 'None', or if the Observer is interested in all
    # events (it was registered with an event list of 'None').
    # @param event The event to notify the Observers about.  None
    # means no specific event.
    # @param msg A reference to any data object that should be passed
    # to the Observers, or None.

    def notifyObservers(self, event=None, msg=None):
        for observer, data in self._observers.items():
            # print("data is", data)
            cbname, events = data
            # print("cbname is", cbname)
            # print("events is", events)
            # print("event is", event)
            if events is None or event is None or event in events:
                # print("observer is " + repr(observer))
                cb = getattr(observer, cbname, None)
                if cb is None:
                    raise NotImplementedError(
                        "Observer has no %s method." % cbname)
                cb(self, event, msg)


#
# The abstract Observer Class
# This class is a mix-in to add Observable registration methods to
# a concrete Observer class.  It is not strictly required.
#

class Observer(object):

    #
    # @param observable The Observable to observe.
    # @param The events this Observer is interested in being
    # notified about.  This should be a tuple or list of events.

    def __init__(self, observable=None, cbname=None, events=None):
        if (observable is not None):
            observable.addObserver(self, cbname, events)

    #
    # Inform an Observable that you would like to be notified when
    # an interesting event occurs in the Observable.
    # @param observable The Observable this Observer would like
    # to observe.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # "update" method.
    # @param events A tuple or list of events this Observer would like
    # to be notified of by the Observer, or None if it would like to
    # be notified of all events.

    def subscribeToObservable(self, observable, cbname=None, events=None):
        assert observable is not None, "Observable is None"
        observable.addObserver(self, cbname, events)

    #
    # Inform an observable that this Observer is no longer interested in it.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the Observable's notification list.
    # Use this function when you want to unsubscribe an Observer
    # without deleting it.
    # @param observable The Observable that this Observer no longer wants
    # to observe.

    def unsubscribeToObservable(self, observable):
        assert observable is not None, "Observable is None"
        observable.removeObserver(self)

# -*- coding: utf-8 -*- # A WeakKeyDictionary is one where, if the object used as the key # gets deleted, automatically removes that key from the # dictionary.  Thus, any Observers which get deleted will be # automatically removed from the observers dictionary, thus having # two effects: # We won't have references to zombie objects in the dictionary, and # We won't have zombie objects, because the reference in this # dictionary won't stay around, and so won't keep the deleted object # alive. # # Add an observer to this Observable's notification list. # @param observer The Observer to add. # @param cbname The name (as a string) of the Observer's # method to call for an event notification, or None for the default # "update" method. # @param events The events the Observer is interested in being # notified about.  None means all events. # # Remove an observer from this Observable's list of observers. # Note that this function is not strictly required, because when a # registered Observer is deleted, the weakref mechanism will cause # it to be removed from the notification list. # @param observer the Observer to remove. # # Notify all currently-registered Observers. # Each observer must have an 'update' method, which should take # three parameters (in addition to self): the Observable, an event, # and a message. # This method will be # called if the event is one that the Observer is interested in, # or if event is 'None', or if the Observer is interested in all # events (it was registered with an event list of 'None'). # @param event The event to notify the Observers about.  None # means no specific event. # @param msg A reference to any data object that should be passed # to the Observers, or None. # print("data is", data) # print("cbname is", cbname) # print("events is", events) # print("event is", event) # print("observer is " + repr(observer)) # # The abstract Observer Class # This class is a mix-in to add Observable registration methods to # a concrete Observer class.  It is not strictly required. # # # @param observable The Observable to observe. # @param The events this Observer is interested in being # notified about.  This should be a tuple or list of events. # # Inform an Observable that you would like to be notified when # an interesting event occurs in the Observable. # @param observable The Observable this Observer would like # to observe. # @param cbname The name (as a string) of the Observer's # method to call for an event notification, or None for the default # "update" method. # @param events A tuple or list of events this Observer would like # to be notified of by the Observer, or None if it would like to # be notified of all events. # # Inform an observable that this Observer is no longer interested in it. # Note that this function is not strictly required, because when a # registered Observer is deleted, the weakref mechanism will cause # it to be removed from the Observable's notification list. # Use this function when you want to unsubscribe an Observer # without deleting it. # @param observable The Observable that this Observer no longer wants # to observe.