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
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 """
97 """ Init the Signal object.
98 """
99 self.__slots = []
100
101
102
103
104 self.__funchost = []
105
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
122 """
123 """
124 self.disconnect(slot)
125 if inspect.ismethod(slot):
126
127
128
129 self.__slots.append(WeakMethod(slot))
130 else:
131 o = _WeakMethod_FuncHost(slot)
132 self.__slots.append(WeakMethod(o.func))
133
134
135 self.__funchost.append(o)
136
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
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
166 """
167 """
169 self.hostedFunction = func
170
171 - def func(self, *args, **kwargs):
172 self.hostedFunction(*args, **kwargs)
173
174
176 """ This class was generously donated by a poster on ASPN
177
178 see aspn.activestate.com
179 """
181 self.f = f.im_func
182 self.c = weakref.ref(f.im_self)
183
185 if self.c() == None:
186 return
187 self.f(self.c(), *args, **kwargs)
188