some minor speedups using caches and more selective updating
authorFelix Domke <tmbinc@elitedvb.net>
Sun, 30 Jul 2006 22:56:43 +0000 (22:56 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sun, 30 Jul 2006 22:56:43 +0000 (22:56 +0000)
17 files changed:
lib/python/Components/Converter/ConditionalShowHide.py
lib/python/Components/Converter/EventName.py
lib/python/Components/Converter/EventTime.py
lib/python/Components/Converter/Poll.py
lib/python/Components/Converter/ServiceInfo.py
lib/python/Components/Converter/ServiceName.py
lib/python/Components/Converter/ServicePosition.py
lib/python/Components/Element.py
lib/python/Components/Renderer/Label.py
lib/python/Components/Renderer/PositionGauge.py
lib/python/Components/Renderer/Progress.py
lib/python/Components/Sources/Boolean.py
lib/python/Components/Sources/Clock.py
lib/python/Components/Sources/CurrentService.py
lib/python/Components/Sources/EventInfo.py
lib/python/Components/Sources/FrontendStatus.py
lib/python/Components/Sources/MenuList.py

index 9f1f86b26bf181bce681679d3deaa1b1629140dc..cc98288f57334884c0ef73e458ef56801258944a 100644 (file)
@@ -6,6 +6,6 @@ class ConditionalShowHide(Converter, object):
                Converter.__init__(self, type)
                self.invert = type == "Invert"
 
-       def changed(self):
+       def changed(self, what):
                for x in self.downstream_elements:
                        x.visible = self.source.boolean
index 2b95d94526d616bdb153be2d2f7d16be1a724275..f128133a7b7bc2c76e34c4f0aa64d170c48e481b 100644 (file)
@@ -15,6 +15,11 @@ class EventName(Converter, object):
                        self.type = self.NAME
 
        def getText(self):
+               if self.cache is None:
+                       self.cache = self.__getText()
+               return self.cache
+
+       def __getText(self):
                event = self.source.event
                if event is None:
                        return "N/A"
index 09fe6bff54422c3e59d5cfd32754b6fdd99305c1..4a73e0acd05cfc501b3b1d3ddb79c2492e2c1973 100644 (file)
@@ -30,6 +30,11 @@ class EventTime(Poll, Converter, object):
                        raise str("'%s' is not <StartTime|EndTime|Remaining|Duration> for EventTime converter" % type)
 
        def getTime(self):
+               if self.cache is None or self.cache[0] is None:
+                       self.cache = (self.__getTime(), self.cache and self.cache[1])
+               return self.cache[0]
+       
+       def __getTime(self):    
                assert self.type != self.PROGRESS
 
                event = self.source.event
@@ -53,6 +58,11 @@ class EventTime(Poll, Converter, object):
                                return (duration, None)
 
        def getValue(self):
+               if self.cache is None or self.cache[1] is None:
+                       self.cache = (self.cache and self.cache[0], self.__getValue())
+               return self.cache[1]
+
+       def __getValue(self):
                assert self.type == self.PROGRESS
 
                event = self.source.event
index 3ba5e87f51cfb1a3825dc624ccee27d2f0c4ec09..2b81e325f53ab5b8c94c94e6f7ab9585eb52c005 100644 (file)
@@ -3,7 +3,7 @@ from enigma import eTimer
 class Poll(object):
        def __init__(self):
                self.__poll_timer = eTimer()
-               self.__poll_timer.timeout.get().append(self.changed)
+               self.__poll_timer.timeout.get().append(self.poll)
                self.__interval = 1000
                self.__enabled = False
 
@@ -20,3 +20,6 @@ class Poll(object):
 
        poll_interval = property(lambda self: self.__interval, __setInterval)
        poll_enabled = property(lambda self: self.__enabled, __setEnable)
+
+       def poll(self):
+               self.changed((self.CHANGED_POLL,))
index f9b65c1975b1b523afdacc9ba235d3fcc99fb7d3..e1351c56e2c5b58b7a7fd19a5a07ea4ff1fd9ca1 100644 (file)
@@ -19,11 +19,11 @@ class ServiceInfo(Converter, object):
                        }[type]
 
                self.interesting_events = {
-                               self.HAS_TELETEXT: [iPlayableService.evEnd, iPlayableService.evUpdatedInfo],
-                               self.IS_MULTICHANNEL: [iPlayableService.evUpdatedInfo, iPlayableService.evEnd],
-                               self.IS_CRYPTED: [iPlayableService.evUpdatedInfo, iPlayableService.evEnd],
-                               self.IS_WIDESCREEN: [iPlayableService.evUpdatedEventInfo, iPlayableService.evEnd],
-                               self.SUBSERVICES_AVAILABLE: [iPlayableService.evUpdatedEventInfo, iPlayableService.evEnd]
+                               self.HAS_TELETEXT: [iPlayableService.evUpdatedInfo],
+                               self.IS_MULTICHANNEL: [iPlayableService.evUpdatedInfo],
+                               self.IS_CRYPTED: [iPlayableService.evUpdatedInfo],
+                               self.IS_WIDESCREEN: [iPlayableService.evUpdatedEventInfo],
+                               self.SUBSERVICES_AVAILABLE: [iPlayableService.evUpdatedEventInfo]
                        }[self.type]
 
        def getServiceInfoValue(self, info, what):
@@ -33,6 +33,11 @@ class ServiceInfo(Converter, object):
                return info.getInfoString(what)
 
        def getBoolean(self):
+               if self.cache is None:
+                       self.cache = self.__getBoolean()
+               return self.cache
+
+       def __getBoolean(self):
                service = self.source.service
                info = service and service.info()
                if not info:
@@ -62,7 +67,6 @@ class ServiceInfo(Converter, object):
 
        boolean = property(getBoolean)
 
-       def changed(self, *args):
-               if not len(args) or args[0] in [iPlayableService.evStart, iPlayableService.evEnd, 
-                       iPlayableService.evUpdatedInfo, iPlayableService.evUpdatedEventInfo]:
-                       Converter.changed(self)
+       def changed(self, what):
+               if what[0] != self.CHANGED_SPECIFIC or what[1] in self.interesting_events:
+                       Converter.changed(self, what)
index 78a3dca2542cf9621887817cadb9e8b17185033c..cffe494dfc9913d914629a7e279707f70cde15dc 100644 (file)
@@ -31,6 +31,6 @@ class ServiceName(Converter, object):
 
        text = property(getText)
 
-       def changed(self, *args):
-               if not len(args) or args[0] in [iPlayableService.evStart, iPlayableService.evEnd]:
-                       Converter.changed(self)
+       def changed(self, what):
+               if what[0] != self.CHANGED_SPECIFIC or what[1] in [iPlayableService.evStart]:
+                       Converter.changed(self, what)
index e072aa5ec1646543f088692e634e6903598a42d9..dfb792addd185543164c1c43207265e293bc8b88 100644 (file)
@@ -70,13 +70,13 @@ class ServicePosition(Converter, Poll, object):
        cutlist = property(getCutlist)
        text = property(getText)
        
-       def changed(self, *args):
-               cutlist_refresh = len(args) and args[0] in [iPlayableService.evCuesheetChanged, iPlayableService.evStart, iPlayableService.evEnd]
-               time_refresh = not len(args) or args[0] in [iPlayableService.evStart, iPlayableService.evEnd]
+       def changed(self, what):
+               cutlist_refresh = what[0] != self.CHANGED_SPECIFIC or what[1] in [iPlayableService.evCuesheetChanged]
+               time_refresh = what[0] == self.CHANGED_POLL or what[0] == self.CHANGED_SPECIFIC and what[1] in [iPlayableService.evCuesheetChanged]
                
                if cutlist_refresh:
                        if self.type == self.TYPE_GAUGE:
                                self.downstream_elements.cutlist_changed()
 
                if time_refresh:
-                       self.downstream_elements.changed()
+                       self.downstream_elements.changed(what)
index 880274b423940ee761435d5c3ef964e45a21b55f..122184661b3435096b599147429a8d481f3301b8 100644 (file)
@@ -5,10 +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.master = None
                self.source = None
+               self.clearCache()
 
        def connectDownstream(self, downstream):
                self.downstream_elements.append(downstream)
@@ -18,7 +25,7 @@ class Element:
        def connectUpstream(self, upstream):
                assert self.source is None
                self.source = upstream
-               self.changed()
+               self.changed((self.CHANGED_DEFAULT,))
        
        def connect(self, upstream):
                self.connectUpstream(upstream)
@@ -44,8 +51,13 @@ class Element:
 
        # default action: push downstream
        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
index 1d06a21490a6fdd0729fbcecc3c11796759525ba..3813ce21beb8f555a5dab7d816c384f3598662de 100644 (file)
@@ -12,7 +12,10 @@ class Label(VariableText, Renderer):
 
        def connect(self, source):
                Renderer.connect(self, source)
-               self.changed()
+               self.changed((self.CHANGED_DEFAULT,))
 
-       def changed(self):
-               self.text = self.source.text
+       def changed(self, what):
+               if what[0] == self.CHANGED_CLEAR:
+                       self.text = ""
+               else:
+                       self.text = self.source.text
index abc9b7ff8ff90fd02112504f3bb0497049223a91..4b49501f7171e3eead576ef8e83a20b83f07a8de 100644 (file)
@@ -11,12 +11,15 @@ class PositionGauge(Renderer):
        GUI_WIDGET = ePositionGauge
        
        def postWidgetCreate(self, instance):
-               self.changed()
+               self.changed((self.CHANGED_DEFAULT,))
                self.cutlist_changed()
                instance.setInOutList(self.__cutlist)
 
-       def changed(self):
-               (self.length, self.position) = (self.source.length or 0, self.source.position or 0)
+       def changed(self, what):
+               if what[0] == self.CHANGED_CLEAR:
+                       (self.length, self.position) = 0
+               else:
+                       (self.length, self.position) = (self.source.length or 0, self.source.position or 0)
 
        def cutlist_changed(self):
                self.cutlist = self.source.cutlist or [ ]
index b6f2b1c88ae8d98649054a3ee0b33d967a2d4c51..f32802e46f339c0e9f2a32bb1c776cc6516efb1b 100644 (file)
@@ -12,7 +12,11 @@ class Progress(VariableValue, Renderer):
 
        GUI_WIDGET = eSlider
 
-       def changed(self):
+       def changed(self, what):
+               if what[0] == self.CHANGED_CLEAR:
+                       (self.range, self.value) = ((0, 1), 0)
+                       return
+
                range = self.source.range or 100
                value = self.source.value
                if value is None:
index c25b4626aafb1eb362a2b7b9c18a7dddf815f573..bd5222afa33008ccd305d213410de865d6c884c8 100644 (file)
@@ -13,7 +13,7 @@ class Boolean(Source, object):
                Source.__init__(self)
                if poll > 0:
                        self.poll_timer = eTimer()
-                       self.poll_timer.timeout.get().append(self.changed)
+                       self.poll_timer.timeout.get().append(self.poll)
                        self.poll_timer.start(poll)
 
        def getBoolean(self):
@@ -23,3 +23,6 @@ class Boolean(Source, object):
                        return self.fixed
 
        boolean = property(getBoolean)
+
+       def poll(self):
+               self.changed((self.CHANGED_ALL,))
index 608a719027f83157cb38f940e28b7e3dfa533c89..e2d7faa7fe1c212104b2069eaf71088618c3aa5e 100644 (file)
@@ -8,10 +8,13 @@ class Clock(Source):
        def __init__(self):
                Source.__init__(self)
                self.clock_timer = eTimer()
-               self.clock_timer.timeout.get().append(self.changed)
+               self.clock_timer.timeout.get().append(self.poll)
                self.clock_timer.start(1000)
 
        def getClock(self):
                return time.time()
 
        time = property(getClock)
+
+       def poll(self):
+               self.changed((self.CHANGED_POLL,))
index 100822bc0cde8255bb88515571d5cb6656d4d699..08d67eeea4acbe11d802e0db34c911226796c2e6 100644 (file)
@@ -2,6 +2,8 @@ from Components.PerServiceDisplay import PerServiceBase
 from enigma import iPlayableService
 from Source import Source
 
+from time import time
+
 class CurrentService(PerServiceBase, Source):
        def __init__(self, navcore):
                Source.__init__(self)
@@ -18,9 +20,11 @@ class CurrentService(PerServiceBase, Source):
                self.navcore = navcore
 
        def serviceEvent(self, event):
-               self.changed(event)
+               self.changed((self.CHANGED_SPECIFIC, event))
 
        def getCurrentService(self):
-               return self.navcore.getCurrentService()
+               if self.cache is None:
+                       self.cache = self.navcore.getCurrentService()
+               return self.cache
 
        service = property(getCurrentService)
index 40269993565795e476da47009ccbbf9138ed045b..20e5f104ed52f84759bdc27b1338a8d39d92f87a 100644 (file)
@@ -3,6 +3,8 @@ from Tools.Event import Event
 from enigma import iPlayableService
 from Source import Source
 
+from time import time
+
 class EventInfo(PerServiceBase, Source, object):
        NOW = 0
        NEXT = 1
@@ -11,16 +13,25 @@ class EventInfo(PerServiceBase, Source, object):
                Source.__init__(self)
                PerServiceBase.__init__(self, navcore, 
                        { 
-                               iPlayableService.evStart: self.changed,
-                               iPlayableService.evUpdatedEventInfo: self.changed,
-                               iPlayableService.evEnd: self.changed
-                       })
+                               iPlayableService.evStart: self.gotEvent,
+                               iPlayableService.evUpdatedEventInfo: self.gotEvent,
+                               iPlayableService.evEnd: self.gotEvent
+                       }, with_event=True)
                
                self.now_or_next = now_or_next
                
        def getEvent(self):
-               service = self.navcore.getCurrentService()
-               info = service and service.info()
-               return info and info.getEvent(self.now_or_next)
+               if self.cache is None:
+                       service = self.navcore.getCurrentService()
+                       info = service and service.info()
+                       self.cache = (True, info and info.getEvent(self.now_or_next)) # we always store a tuple for negative caching
+               
+               return self.cache[1]
 
        event = property(getEvent)
+
+       def gotEvent(self, what):
+               if what in [iPlayableService.evStart, iPlayableService.evEnd]:
+                       self.changed((self.CHANGED_CLEAR,))
+               else:
+                       self.changed((self.CHANGED_ALL,))
index 6682e8290cfbecabd1cb5c92cff3700f56401809..f1402f110863d1f06ec979ea8302f16ffdb63251 100644 (file)
@@ -27,7 +27,7 @@ class FrontendStatus(Source):
                                                iFrontendInformation.bitErrorRate, 
                                                iFrontendInformation.lockState] ]
 
-               self.changed()
+               self.changed((self.CHANGED_ALL, ))
 
        def getFrontendInfo(self):
                if self.frontend_source:
index 98764418b8f4a588af488d1a89f79fb7c16c5ea2..dd5e18f78f901e7ecef88f5f0080f871bf94e6ca 100644 (file)
@@ -9,7 +9,7 @@ class MenuList(Source, object):
        
        def setList(self, list):
                self.__list = list
-               self.changed()
+               self.changed((self.CHANGED_ALL,))
        
        list = property(lambda self: self.__list, setList)