X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fpython%2FComponents%2FElement.py;h=3297a4adf80a4af6dce071f9d629920aa9e8003f;hp=122184661b3435096b599147429a8d481f3301b8;hb=db34d7e342d82f9767045de76b791fee2357bbc4;hpb=1557c715e461d5a7deb04bb008c6497441351bbe diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py index 1221846..3297a4a 100644 --- a/lib/python/Components/Element.py +++ b/lib/python/Components/Element.py @@ -4,18 +4,41 @@ from Tools.CList import CList # Render Converter Converter Source # a bidirectional connection -class Element: + +def cached(f): + name = f.__name__ + def wrapper(self): + cache = self.cache + if cache is None: + return f(self) + if name not in cache: + cache[name] = (True, f(self)) + return cache[name][1] + return wrapper + +class ElementError(Exception): + def __init__(self, message): + self.msg = message + + def __str__(self): + return self.msg + +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 + SINGLE_SOURCE = True + def __init__(self): self.downstream_elements = CList() self.master = None + self.sources = [ ] self.source = None - self.clearCache() + self.__suspended = True + self.cache = None def connectDownstream(self, downstream): self.downstream_elements.append(downstream) @@ -23,7 +46,9 @@ class Element: self.master = downstream def connectUpstream(self, upstream): - assert self.source is None + assert not self.SINGLE_SOURCE or self.source is None + self.sources.append(upstream) + # self.source always refers to the last recent source added. self.source = upstream self.changed((self.CHANGED_DEFAULT,)) @@ -36,11 +61,17 @@ class Element: # we should not disconnect from upstream if # there are still elements depending on us. assert len(self.downstream_elements) == 0, "there are still downstream elements left" - + # Sources don't have a source themselves. don't do anything here. - if self.source is not None: - self.source.disconnectDownstream(self) - + for s in self.sources: + s.disconnectDownstream(self) + + if self.source: + # sources are owned by the Screen, so don't destroy them here. + self.destroy() + self.source = None + self.sources = [ ] + def disconnectDownstream(self, downstream): self.downstream_elements.remove(downstream) if self.master == downstream: @@ -51,13 +82,29 @@ class Element: # default action: push downstream def changed(self, *args, **kwargs): - self.clearCache() + self.cache = { } self.downstream_elements.changed(*args, **kwargs) - self.clearCache() + 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 changed: + for s in self.sources: + s.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 clearCache(self): - self.cache = None + def doSuspend(self, suspend): + pass + + def destroy(self): + pass