Package _Framework :: Module Signal
[hide private]
[frames] | no frames]

Source Code for Module _Framework.Signal

  1  #Embedded file name: /Users/versonator/Hudson/live/Projects/AppLive/Resources/MIDI Remote Scripts/_Framework/Signal.py 
  2  from Util import find_if, nop 
  3  from functools import partial 
4 5 -def default_combiner(results):
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
16 - def __call__(self, *a, **k):
17 return self.callback(*a, **k)
18
19 - def __eq__(self, other):
20 return id(self) == id(other) or self.callback == other
21
22 23 -class IdentifyingSlot(Slot):
24
25 - def __init__(self, sender = None, *a, **k):
26 super(IdentifyingSlot, self).__init__(*a, **k) 27 self.sender = sender
28
29 - def __call__(self, *a, **k):
30 self.callback(*(a + (self.sender,)), **k)
31
32 33 -class Signal(object):
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
44 - def __init__(self, combiner = default_combiner, sender = None, *a, **k):
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
73 - def disconnect(self, slot):
74 if slot in self._slots: 75 self._slots.remove(slot)
76
77 - def disconnect_all(self):
78 self._slots = []
79 80 @property
81 - def count(self):
82 return len(self._slots)
83
84 - def is_connected(self, slot):
85 return slot in self._slots
86
87 - def __call__(self, *a, **k):
88 return self._combiner(_slot_notification_generator(self._slots, a, k))
89
90 91 -def _slot_notification_generator(slots, args, kws):
92 for slot in slots: 93 yield slot(*args, **kws)
94
95 96 -def short_circuit_combiner(slot_results):
97 return find_if(nop, slot_results)
98 99 100 short_circuit_signal = partial(Signal, short_circuit_combiner) 101