X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fpython%2FComponents%2FElement.py;h=baab4cfb46d30284be8d3836d61e346e49a8b5bf;hp=5b8bed866cf1368c88fbb8574b7e46121fc87726;hb=e03c732afb410b4d6b9f9540c36c33c941ee38f1;hpb=732961ea798182d334d26e2fa2ce8d91672a932f diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py index 5b8bed8..baab4cf 100644 --- a/lib/python/Components/Element.py +++ b/lib/python/Components/Element.py @@ -4,12 +4,30 @@ from Tools.CList import CList # Render Converter Converter Source # a bidirectional connection -class Element: + +def cached(f): + name = f.__name__ + def wrapper(self): + if self.cache is None: + return f(self) + if name not in self.cache: + self.cache[name] = (True, f(self)) + return self.cache[name][1] + return wrapper + +class Element(object): + CHANGED_DEFAULT = 0 # initial "pull" state + CHANGED_ALL = 1 # really everything changed + CHANGED_CLEAR = 2 # we're expecting a real update soon. don't bother polling NOW, but clear data. + CHANGED_SPECIFIC = 3 # second tuple will specify what exactly changed + CHANGED_POLL = 4 # a timer expired + def __init__(self): self.downstream_elements = CList() - self.upstream_elements = CList() self.master = None self.source = None + self.__suspended = True + self.cache = None def connectDownstream(self, downstream): self.downstream_elements.append(downstream) @@ -17,9 +35,9 @@ class Element: self.master = downstream def connectUpstream(self, upstream): - self.upstream_elements.append(upstream) - self.source = upstream # for single-source elements (i.e., most of them.) - self.changed() + assert self.source is None + self.source = upstream + self.changed((self.CHANGED_DEFAULT,)) def connect(self, upstream): self.connectUpstream(upstream) @@ -31,9 +49,9 @@ class Element: # there are still elements depending on us. assert len(self.downstream_elements) == 0, "there are still downstream elements left" - # disconnect all upstream elements from us - for upstream in self.upstream_elements: - upstream.disconnectDownstream(self) + # Sources don't have a source themselves. don't do anything here. + if self.source is not None: + self.source.disconnectDownstream(self) def disconnectDownstream(self, downstream): self.downstream_elements.remove(downstream) @@ -45,4 +63,29 @@ class Element: # default action: push downstream def changed(self, *args, **kwargs): + self.cache = { } self.downstream_elements.changed(*args, **kwargs) + self.cache = None + + def reconnectUpstream(self, new_upstream): + assert self.source is not None + self.source = new_upstream + + def setSuspend(self, suspended): + changed = self.__suspended != suspended + if not self.__suspended and suspended: + self.doSuspend(1) + elif self.__suspended and not suspended: + self.doSuspend(0) + + self.__suspended = suspended + if self.source is not None and changed: + self.source.checkSuspend() + + suspended = property(lambda self: self.__suspended, setSuspend) + + def checkSuspend(self): + self.suspended = reduce(lambda x, y: x and y.__suspended, self.downstream_elements, True) + + def doSuspend(self, suspend): + pass