1 from Tools.CList import CList
4 # Render Converter Converter Source
6 # a bidirectional connection
15 cache[name] = (True, f(self))
19 class ElementError(Exception):
20 def __init__(self, message):
26 class Element(object):
27 CHANGED_DEFAULT = 0 # initial "pull" state
28 CHANGED_ALL = 1 # really everything changed
29 CHANGED_CLEAR = 2 # we're expecting a real update soon. don't bother polling NOW, but clear data.
30 CHANGED_SPECIFIC = 3 # second tuple will specify what exactly changed
31 CHANGED_POLL = 4 # a timer expired
34 self.downstream_elements = CList()
37 self.__suspended = True
40 def connectDownstream(self, downstream):
41 self.downstream_elements.append(downstream)
42 if self.master is None:
43 self.master = downstream
45 def connectUpstream(self, upstream):
46 assert self.source is None
47 self.source = upstream
48 self.changed((self.CHANGED_DEFAULT,))
50 def connect(self, upstream):
51 self.connectUpstream(upstream)
52 upstream.connectDownstream(self)
54 # we disconnect from down to up
55 def disconnectAll(self):
56 # we should not disconnect from upstream if
57 # there are still elements depending on us.
58 assert len(self.downstream_elements) == 0, "there are still downstream elements left"
60 # Sources don't have a source themselves. don't do anything here.
61 if self.source is not None:
62 self.source.disconnectDownstream(self)
63 # sources are owned by the Screen, so don't destroy them here.
66 def disconnectDownstream(self, downstream):
67 self.downstream_elements.remove(downstream)
68 if self.master == downstream:
71 if len(self.downstream_elements) == 0:
74 # default action: push downstream
75 def changed(self, *args, **kwargs):
77 self.downstream_elements.changed(*args, **kwargs)
80 def reconnectUpstream(self, new_upstream):
81 assert self.source is not None
82 self.source = new_upstream
84 def setSuspend(self, suspended):
85 changed = self.__suspended != suspended
86 if not self.__suspended and suspended:
88 elif self.__suspended and not suspended:
91 self.__suspended = suspended
92 if self.source is not None and changed:
93 self.source.checkSuspend()
95 suspended = property(lambda self: self.__suspended, setSuspend)
97 def checkSuspend(self):
98 self.suspended = reduce(lambda x, y: x and y.__suspended, self.downstream_elements, True)
100 def doSuspend(self, suspend):