add stv0299 snr to dB Calculation (thx to adenin for this)
[enigma2.git] / lib / python / Components / Element.py
1 from Tools.CList import CList
2
3 # down                       up
4 # Render Converter Converter Source
5
6 # a bidirectional connection
7
8 def cached(f):
9         name = f.__name__
10         def wrapper(self):
11                 if self.cache is None:
12                         return f(self)
13                 if name not in self.cache:
14                         self.cache[name] = (True, f(self))
15                 return self.cache[name][1]
16         return wrapper
17
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
24
25         def __init__(self):
26                 self.downstream_elements = CList()
27                 self.master = None
28                 self.source = None
29                 self.__suspended = True
30                 self.cache = None
31
32         def connectDownstream(self, downstream):
33                 self.downstream_elements.append(downstream)
34                 if self.master is None:
35                         self.master = downstream
36         
37         def connectUpstream(self, upstream):
38                 assert self.source is None
39                 self.source = upstream
40                 self.changed((self.CHANGED_DEFAULT,))
41         
42         def connect(self, upstream):
43                 self.connectUpstream(upstream)
44                 upstream.connectDownstream(self)
45
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"
51                 
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)
55         
56         def disconnectDownstream(self, downstream):
57                 self.downstream_elements.remove(downstream)
58                 if self.master == downstream:
59                         self.master = None
60                 
61                 if len(self.downstream_elements) == 0:
62                         self.disconnectAll()
63
64         # default action: push downstream
65         def changed(self, *args, **kwargs):
66                 self.cache = { }
67                 self.downstream_elements.changed(*args, **kwargs)
68                 self.cache = None
69
70         def reconnectUpstream(self, new_upstream):
71                 assert self.source is not None
72                 self.source = new_upstream
73
74         def setSuspend(self, suspended):
75                 changed = self.__suspended != suspended
76                 if not self.__suspended and suspended:
77                         self.doSuspend(1)
78                 elif self.__suspended and not suspended:
79                         self.doSuspend(0)
80                         
81                 self.__suspended = suspended
82                 if self.source is not None and changed:
83                         self.source.checkSuspend()
84         
85         suspended = property(lambda self: self.__suspended, setSuspend)
86         
87         def checkSuspend(self):
88                 self.suspended = reduce(lambda x, y: x and y.__suspended, self.downstream_elements, True)
89
90         def doSuspend(self, suspend):
91                 pass