Package imagizer :: Module signals |
[hide private]
[frames] | no frames]

# Source Code for Module imagizer.signals

      1  """ Provide Signal class.
      2
      3  A signals implementation.
      4
      5  Example usage
      6  =============
      7
      8  >>> class Button:
      9  ...     def __init__(self):
     10  ...         # Creating a signal as a member of a class
     11  ...         self.sigClick = Signal()
     12
     13  >>> class Listener:
     14  ...     # a sample method that will be connected to the signal
     15  ...     def onClick(self):
     16  ...         print "onClick ", repr(self)
     17
     18  >>> # a sample function to connect to the signal
     19  >>> def listenFunction():
     20  ...     print "listenFunction"
     21
     22  >>> # a function that accepts arguments
     23  >>> def listenWithArgs(text):
     24  ...     print "listenWithArgs: ", text
     25
     26  >>> b = Button()
     27  >>> l = Listener()
     28
     29  >>> b.sigClick.connect(l.onClick)
     30  >>> b.sigClick()
     31  onClick  <__main__.Listener instance at 0x4024cf2c>
     32
     33  >>> # Disconnecting all signals
     34  >>> b.sigClick.disconnectAll()
     35  >>> b.sigClick()
     36
     37  >>> # connecting multiple functions to a signal
     38  >>> l2 = Listener()
     39  >>> b.sigClick.connect(l.onClick)
     40  >>> b.sigClick.connect(l2.onClick)
     41  >>> b.sigClick()
     42  onClick  <__main__.Listener instance at 0x4024cf2c>
     43  onClick  <__main__.Listener instance at 0x4024ce0c>
     44
     45  >>> # disconnecting individual functions
     46  >>> b.sigClick.disconnect(l.onClick)
     47  >>> b.sigClick.connect(listenFunction)
     48  >>> b.sigClick()
     49  onClick  <__main__.Listener instance at 0x4024ce0c>
     50  listenFunction
     51
     52  >>> # signals disconnecting automatically
     53  >>> b.sigClick.disconnectAll()
     54  >>> b.sigClick.connect(l.onClick)
     55  >>> b.sigClick.connect(l2.onClick)
     56  >>> del l2
     57  >>> b.sigClick()
     58  onClick  <__main__.Listener instance at 0x4024cf2c>
     59
     60  >>> # example with arguments and a local signal
     61  >>> sig = Signal()
     62  >>> sig.connect(listenWithArgs)
     63  >>> sig("Hello, World!")
     64  listenWithArgs:  Hello, World!
     65
     66
     67  Based on a Patrick Chasco's code.
     68
     69  @author: Benjamin Longuet
     70  @author: Frederic Mantegazza
     71  @author: Cyrille Boullier
     72  @copyright: 2003-2005
     73  @organization: CEA-Grenoble
     74  @license: GPL
     75  """
     76
     77  __revision__ = "$Id: imagizer.signals-pysrc.html,v 1.1 2010-04-28 19:44:10 jerome Exp $"
     78
     79  import weakref
     80  import inspect
     81  import sets
     82
     83
     84 -class Signal(object):
     85      """ class Signal.
     86
     87      A simple implementation of the Signal/Slot pattern. To use, simply
     88      create a Signal instance. The instance may be a member of a class,
     89      a global, or a local; it makes no difference what scope it resides
     90      within. Connect slots to the signal using the "connect()" method.
     91      The slot may be a member of a class or a simple function. If the
     92      slot is a member of a class, Signal will automatically detect when
     93      the method's class instance has been deleted and remove it from
     94      its list of connected slots.
     95      """
     96 -    def __init__(self):
     97          """ Init the Signal object.
     98          """
     99          self.__slots = []
    100
    101          # for keeping references to _WeakMethod_FuncHost objects.
    102          # If we didn't, then the weak references would die for
    103          # non-method slots that we've created.
    104          self.__funchost = []
    105
    106 -    def __call__(self, *args, **kwargs):
    107          """
    108          """
    109          for i in xrange(len(self.__slots)):
    110              slot = self.__slots[i]
    111              if slot != None:
    112                  slot(*args, **kwargs)
    113              else:
    114                  del self.__slots[i]
    115
    116 -    def emit(self, *args, **kwargs):
    117          """
    118          """
    119          self.__call__(*args, **kwargs)
    120
    121 -    def connect(self, slot): # , keepRef=False):
    122          """
    123          """
    124          self.disconnect(slot)
    125          if inspect.ismethod(slot):
    126              #if keepRef:
    127                  #self.__slots.append(slot)
    128              #else:
    129              self.__slots.append(WeakMethod(slot))
    130          else:
    131              o = _WeakMethod_FuncHost(slot)
    132              self.__slots.append(WeakMethod(o.func))
    133
    134              # we stick a copy in here just to keep the instance alive
    135              self.__funchost.append(o)
    136
    137 -    def disconnect(self, slot):
    138          """
    139          """
    140          try:
    141              for i in xrange(len(self.__slots)):
    142                  wm = self.__slots[i]
    143                  if inspect.ismethod(slot):
    144                      if wm.f == slot.im_func and wm.c() == slot.im_self:
    145                          del self.__slots[i]
    146                          return
    147                  else:
    148                      if wm.c().hostedFunction == slot:
    149                          del self.__slots[i]
    150                          return
    151          except:
    152              pass
    153
    154 -    def disconnectAll(self):
    155          """
    156          """
    157          del self.__slots
    158          del self.__funchost
    159          del self.__methodhost
    160          self.__slots = []
    161          self.__funchost = []
    162          self.__methodhost = []
    163
    164
    165 -class _WeakMethod_FuncHost:
    166      """
    167      """
    168 -    def __init__(self, func):
    169          self.hostedFunction = func
    170
    171 -    def func(self, *args, **kwargs):
    172          self.hostedFunction(*args, **kwargs)
    173
    174
    175 -class WeakMethod:
    176      """ This class was generously donated by a poster on ASPN
    177
    178      see aspn.activestate.com
    179      """
    180 -    def __init__(self, f):
    181          self.f = f.im_func
    182          self.c = weakref.ref(f.im_self)
    183
    184 -    def __call__(self, *args, **kwargs):
    185          if self.c() == None:
    186              return
    187          self.f(self.c(), *args, **kwargs)
    188