some minor speedups using caches and more selective updating
[vuplus_dvbapp] / lib / python / Components / Element.py
index 6f812b2..1221846 100644 (file)
@@ -5,11 +5,17 @@ from Tools.CList import CList
 
 # a bidirectional connection
 class Element:
+       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.clearCache()
 
        def connectDownstream(self, downstream):
                self.downstream_elements.append(downstream)
@@ -17,14 +23,41 @@ 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)
                upstream.connectDownstream(self)
 
+       # we disconnect from down to up
+       def disconnectAll(self):
+               # 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)
+       
+       def disconnectDownstream(self, downstream):
+               self.downstream_elements.remove(downstream)
+               if self.master == downstream:
+                       self.master = None
+               
+               if len(self.downstream_elements) == 0:
+                       self.disconnectAll()
+
        # default action: push downstream
-       def changed(self):
-               self.downstream_elements.changed()
+       def changed(self, *args, **kwargs):
+               self.clearCache()
+               self.downstream_elements.changed(*args, **kwargs)
+               self.clearCache()
+
+       def reconnectUpstream(self, new_upstream):
+               assert self.source is not None
+               self.source = new_upstream
+
+       def clearCache(self):
+               self.cache = None