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$" 
 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