Let's suppose that I want create new InfoBarBase Screen:
class MyInfoBar(InfoBarBase, Screen):
def __init__(self, session):
Screen.__init__(self, session)
InfoBarBase.__init__(self)
When I start playing some service while in MyInfoBar and evBuffering messages are emitted, then buffering messages are shown. But they should be only shown when InfoBarBuffer is part of MyInfoBar, which is not the case.
ServiceEventTracker.event is filtering which events should be executed in which Screen.
ServiceEventTracker.event, with added debug messages for evBuffering:
@staticmethod
def event(evt):
............
for func in func_list:
#debug_start
if evt == iPlayableService.evBuffering:
print "evBuffering - passAll: %s, screen: %s, function: %s" %(str(func[0]), str(func[1]), str(func[2]))
#debug_end
if (func[0] or # let pass all events to screens not derived from InfoBarBase
(not old_service_running and stack[ssize-1] == func[1]) or # let pass events from currently running service just to current active screen (derived from InfoBarBase)
(old_service_running and ssize > 1 and stack[ssize-2] == func[1])): # let pass events from old running service just to previous active screen (derived from InfoBarBase)
func[2]()
result without modification:
Buffering 5 percent done
evBuffering - passAll: True, screen: <class 'Screens.InfoBarGenerics.BufferIndicator'>, function: <bound method BufferIndicator.bufferChanged of <class 'Screens.InfoBarGenerics.BufferIndicator'
This means that function bufferChanged will be called even if I don't include InfoBarBuffer in MyInfoBar, since passall is set to True.
ServiceEventTracker:
def __init__(self, screen, eventmap):
.................
self.__passall = not isinstance(screen, InfoBarBase) # let pass all events to screens not derived from InfoBarBase
.................
Result with modification:
evBuffering - passAll: False, screen: <class 'Screens.InfoBar.InfoBar'>, function: <bound method InfoBar.__bufferChanged of <class 'Screens.InfoBar.InfoBar'>>
passall is set to False, since InfoBarBuffer is part of InfoBarBase and InfoBar.__bufferChanged will be not called when MyInfoBar is active
I was thinking and we should also make sure that bufferScreen is hidden onExecEnd, in case new InfoBarBase Screen is created right between evStart and evGstreamerPlayStarted.
diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py
index 0e4cb62..17e3303 100644
--- a/lib/python/Screens/InfoBarGenerics.py
+++ b/lib/python/Screens/InfoBarGenerics.py
@@ -369,7 +369,6 @@ class BufferIndicator(Screen):
self.mayShow = False
self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
{
- iPlayableService.evBuffering: self.bufferChanged,
iPlayableService.evStart: self.__evStart,
iPlayableService.evGstreamerPlayStarted: self.__evGstreamerPlayStarted,
})
@@ -397,6 +396,18 @@ class InfoBarBuffer():
def __init__(self):
self.bufferScreen = self.session.instantiateDialog(BufferIndicator)
self.bufferScreen.hide()
+ self.onExecEnd.append(self.__onExecEnd)
+ self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+ {
+ iPlayableService.evBuffering: self.__bufferChanged,
+ })
+
+ def __onExecEnd(self):
+ if self.bufferScreen.shown:
+ self.bufferScreen.hide()
+
+ def __bufferChanged(self):
+ self.bufferScreen.bufferChanged()