Source code for pysap.base.observable

# -*- coding: utf-8 -*-
##########################################################################
# pySAP - Copyright (C) CEA, 2017 - 2018
# Distributed under the terms of the CeCILL-B license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
# for details.
##########################################################################


[docs]class SignalObject(object): """ Dummy class for signals. """ pass
[docs]class Observable(object): """ Base class for observable classes. This class defines a simple interface to add or remove observers on an object. """ def __init__(self, signals): """ Initilize the Observable class. Parameters ---------- signals: list of str the allowed signals. """ # Define class parameters self._allowed_signals = [] self._observers = {} # Set allowed signals for signal in signals: self._allowed_signals.append(signal) self._observers[signal] = [] # Set a lock option to avoid multiple observer notifications self._locked = False
[docs] def add_observer(self, signal, observer): """ Add an observer to the object. Raise an exception if the signal is not allowed. Parameters ---------- signal: str a valid signal. observer: callable a function that will be called when the signal is emitted. """ self._is_allowed_signal(signal) self._add_observer(signal, observer)
[docs] def remove_observer(self, signal, observer): """ Remove an observer from the object. Raise an eception if the signal is not allowed. Parameters ---------- signal: str a valid signal. observer: callable an obervation function to be removed. """ self._is_allowed_event(signal) self._remove_observer(signal, observer)
[docs] def notify_observers(self, signal, **kwargs): """ Notify observers of a given signal. Parameters ---------- signal: str a valid signal. kwargs: dict the parameters that will be sent to the observers. Returns ------- out: bool Fasle if a notification is in progress, otherwise True. """ # Chack if a notification if in progress if self._locked: return False # Set the lock self._locked = True # Create a signal object signal_to_be_notified = SignalObject() setattr(signal_to_be_notified, "object", self) setattr(signal_to_be_notified, "signal", signal) for name, value in kwargs.items(): setattr(signal_to_be_notified, name, value) # Notify all the observers for observer in self._observers[signal]: observer(signal_to_be_notified) # Unlock the notification process self._locked = False
###################################################################### # Properties ######################################################################
[docs] def _get_allowed_signals(self): """ Events allowed for the current object. """ return self._allowed_signals
allowed_signals = property(_get_allowed_signals) ###################################################################### # Private interface ######################################################################
[docs] def _is_allowed_signal(self, signal): """ Check if a signal is valid. Raise an exception if the signal is not allowed. Parameters ---------- signal: str a signal. """ if signal not in self._allowed_signals: raise Exception("Signal '{0}' is not allowed for '{1}'.".format( signal, type(self)))
[docs] def _add_observer(self, signal, observer): """ Assocaite an observer to a valid signal. Parameters ---------- signal: str a valid signal. observer: callable an obervation function. """ if observer not in self._observers[signal]: self._observers[signal].append(observer)
[docs] def _remove_observer(self, signal, observer): """ Remove an observer to a valid signal. Parameters ---------- signal: str a valid signal. observer: callable an obervation function to be removed. """ if observer in self._observers[signal]: self._observers[signal].remove(observer)