1
2 from Util import find_if, nop
3 from functools import partial
6 for _ in results:
7 pass
8
9
10 -class Slot(object):
11
12 - def __init__(self, callback = None, *a, **k):
13 super(Slot, self).__init__(*a, **k)
14 self.callback = callback
15
17 return self.callback(*a, **k)
18
20 return id(self) == id(other) or self.callback == other
21
24
25 - def __init__(self, sender = None, *a, **k):
28
30 self.callback(*(a + (self.sender,)), **k)
31
34 """
35 A signal object implements the observer pattern. It can be
36 connected to any number of slots (i.e. callbacks). Whenever the
37 signal is called, all the slots are called.
38
39 The return value of this function will depend on the combiner.
40 The combiner takes a generator of slot results and returns a
41 value. The slots whose results are not evaluated are not called.
42 """
43
45 super(Signal, self).__init__(*a, **k)
46 self._slots = []
47 self._combiner = combiner
48
49 - def connect(self, slot, in_front = False, sender = None):
50 """
51 Connects the signal to the slot. Does nothing if the slot is
52 already connected. Returns the wrapper object that is used as
53 a slot.
54
55 If 'in_front' is True, the slot will be put first, meaning it
56 will be called before previously registered slots (by default
57 it is put last).
58
59 If 'sender' is not None, it will be passed as last ordinal
60 parameter to the slot when the signal is dispatched.
61 """
62 if not callable(slot):
63 raise AssertionError
64 if slot not in self._slots:
65 slot = IdentifyingSlot(sender, slot) if sender is not None else Slot(slot)
66 in_front and self._slots.insert(0, slot)
67 else:
68 self._slots.append(slot)
69 else:
70 slot = find_if(lambda x: x == slot, self._slots)
71 return slot
72
74 if slot in self._slots:
75 self._slots.remove(slot)
76
79
80 @property
82 return len(self._slots)
83
85 return slot in self._slots
86
89
92 for slot in slots:
93 yield slot(*args, **kws)
94
98
99
100 short_circuit_signal = partial(Signal, short_circuit_combiner)
101