1 from Tools.CList import CList
4 # Render Converter Converter Source
6 # a bidirectional connection
11 if self.cache is None:
13 if name not in self.cache:
14 self.cache[name] = (True, f(self))
15 return self.cache[name][1]
18 class Element(object):
19 CHANGED_DEFAULT = 0 # initial "pull" state
20 CHANGED_ALL = 1 # really everything changed
21 CHANGED_CLEAR = 2 # we're expecting a real update soon. don't bother polling NOW, but clear data.
22 CHANGED_SPECIFIC = 3 # second tuple will specify what exactly changed
23 CHANGED_POLL = 4 # a timer expired
26 self.downstream_elements = CList()
29 self.__suspended = True
32 def connectDownstream(self, downstream):
33 self.downstream_elements.append(downstream)
34 if self.master is None:
35 self.master = downstream
37 def connectUpstream(self, upstream):
38 assert self.source is None
39 self.source = upstream
40 self.changed((self.CHANGED_DEFAULT,))
42 def connect(self, upstream):
43 self.connectUpstream(upstream)
44 upstream.connectDownstream(self)
46 # we disconnect from down to up
47 def disconnectAll(self):
48 # we should not disconnect from upstream if
49 # there are still elements depending on us.
50 assert len(self.downstream_elements) == 0, "there are still downstream elements left"
52 # Sources don't have a source themselves. don't do anything here.
53 if self.source is not None:
54 self.source.disconnectDownstream(self)
56 def disconnectDownstream(self, downstream):
57 self.downstream_elements.remove(downstream)
58 if self.master == downstream:
61 if len(self.downstream_elements) == 0:
64 # default action: push downstream
65 def changed(self, *args, **kwargs):
67 self.downstream_elements.changed(*args, **kwargs)
70 def reconnectUpstream(self, new_upstream):
71 assert self.source is not None
72 self.source = new_upstream
74 def setSuspend(self, suspended):
75 changed = self.__suspended != suspended
76 if not self.__suspended and suspended:
78 elif self.__suspended and not suspended:
81 self.__suspended = suspended
82 if self.source is not None and changed:
83 self.source.checkSuspend()
85 suspended = property(lambda self: self.__suspended, setSuspend)
87 def checkSuspend(self):
88 self.suspended = reduce(lambda x, y: x and y.__suspended, self.downstream_elements, True)
90 def doSuspend(self, suspend):