diff options
author | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2017-03-19 22:48:52 +0100 |
---|---|---|
committer | Kai Sommerfeld <kai.sommerfeld@gmx.com> | 2017-03-26 21:02:00 +0200 |
commit | 3bcba5bb2a8956ff6254f1c8308fd3215966ce84 (patch) | |
tree | 1c6822a3d2924d5e142ac48d315d6c172a2570b0 | |
parent | cbd96778cf947793f709c0e8508a085f5f101f2e (diff) |
[PVR] Guide window: Implement asynchronous channel group switching.
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRGuide.cpp | 61 | ||||
-rw-r--r-- | xbmc/pvr/windows/GUIWindowPVRGuide.h | 6 |
2 files changed, 52 insertions, 15 deletions
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp index 2193f951c3..b74cc36030 100644 --- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp @@ -19,6 +19,7 @@ */ #include "ContextMenuManager.h" +#include "dialogs/GUIDialogBusy.h" #include "epg/GUIEPGGridContainer.h" #include "GUIUserMessages.h" #include "epg/EpgContainer.h" @@ -41,8 +42,7 @@ using namespace PVR; using namespace EPG; CGUIWindowPVRGuide::CGUIWindowPVRGuide(bool bRadio) : - CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_GUIDE : WINDOW_TV_GUIDE, "MyPVRGuide.xml"), - m_cachedChannelGroup(new CPVRChannelGroup) + CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_GUIDE : WINDOW_TV_GUIDE, "MyPVRGuide.xml") { m_bRefreshTimelineItems = false; g_EpgContainer.RegisterObserver(this); @@ -68,15 +68,15 @@ void CGUIWindowPVRGuide::Init() epgGridContainer->GoToNow(); } - m_bRefreshTimelineItems = true; StartRefreshTimelineItemsThread(); + m_bRefreshTimelineItems = true; // force data update on window open/re-open } void CGUIWindowPVRGuide::ClearData() { { CSingleLock lock(m_critSection); - m_cachedChannelGroup.reset(new CPVRChannelGroup); + m_cachedChannelGroup.reset(); m_newTimeline.reset(); } @@ -97,7 +97,6 @@ void CGUIWindowPVRGuide::OnInitWindow() void CGUIWindowPVRGuide::OnDeinitWindow(int nextWindowID) { StopRefreshTimelineItemsThread(); - m_bRefreshTimelineItems = false; CGUIWindowPVRBase::OnDeinitWindow(nextWindowID); } @@ -112,7 +111,10 @@ void CGUIWindowPVRGuide::StartRefreshTimelineItemsThread() void CGUIWindowPVRGuide::StopRefreshTimelineItemsThread() { if (m_refreshTimelineItemsThread) - m_refreshTimelineItemsThread->StopThread(false); + { + m_bRefreshTimelineItems = false; + m_refreshTimelineItemsThread->Stop(); + } } void CGUIWindowPVRGuide::Notify(const Observable &obs, const ObservableMessage msg) @@ -562,20 +564,22 @@ bool CGUIWindowPVRGuide::RefreshTimelineItems() void CGUIWindowPVRGuide::GetViewTimelineItems(CFileItemList &items) { - bool bRefresh = false; + bool bRefreshTimelineItems = false; + { CSingleLock lock(m_critSection); - if (!m_bRefreshTimelineItems && *m_cachedChannelGroup != *GetChannelGroup()) + if (m_cachedChannelGroup && *m_cachedChannelGroup != *GetChannelGroup()) { + // channel group change and not very first open of this window. force immediate update. m_bRefreshTimelineItems = true; - bRefresh = true; + bRefreshTimelineItems = true; } } - // never call RefreshTimelineItems with locked mutex! - if (bRefresh) - RefreshTimelineItems(); + // never call DoRefresh with locked mutex! + if (bRefreshTimelineItems) + m_refreshTimelineItemsThread->DoRefresh(); { CSingleLock lock(m_critSection); @@ -704,8 +708,23 @@ bool CGUIWindowPVRGuide::OnContextButtonDeleteTimer(CFileItem *item, CONTEXT_BUT CPVRRefreshTimelineItemsThread::CPVRRefreshTimelineItemsThread(CGUIWindowPVRGuide *pGuideWindow) : CThread("epg-grid-refresh-timeline-items"), - m_pGuideWindow(pGuideWindow) + m_pGuideWindow(pGuideWindow), + m_ready(true), + m_done(false) +{ +} + +void CPVRRefreshTimelineItemsThread::Stop() { + StopThread(false); + m_ready.Set(); // wake up the worker thread to let it exit +} + +void CPVRRefreshTimelineItemsThread::DoRefresh() +{ + m_ready.Set(); // wake up the worker thread + m_done.Reset(); + CGUIDialogBusy::WaitOnEvent(m_done, 100, false); } void CPVRRefreshTimelineItemsThread::Process() @@ -717,12 +736,19 @@ void CPVRRefreshTimelineItemsThread::Process() while (!m_bStop) { + m_done.Reset(); + if (m_pGuideWindow->RefreshTimelineItems() && !m_bStop) { CGUIMessage m(GUI_MSG_REFRESH_LIST, m_pGuideWindow->GetID(), 0, ObservableMessageEpg); KODI::MESSAGING::CApplicationMessenger::GetInstance().SendGUIMessage(m); } + if (m_bStop) + break; + + m_done.Set(); + // in order to fill the guide window asap, use a short update interval until we the // same amount of epg events for BOOSTED_SLEEPS_THRESHOLD + 1 times in a row . if (iUpdatesWithoutChange < BOOSTED_SLEEPS_THRESHOLD) @@ -736,11 +762,16 @@ void CPVRRefreshTimelineItemsThread::Process() iLastEpgItemsCount = iCurrentEpgItemsCount; - Sleep(1000); // boosted update cycle + m_ready.WaitMSec(1000); // boosted update cycle } else { - Sleep(5000); // normal update cycle + m_ready.WaitMSec(5000); // normal update cycle } + + m_ready.Reset(); } + + m_ready.Reset(); + m_done.Set(); } diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.h b/xbmc/pvr/windows/GUIWindowPVRGuide.h index d5a41fc353..c4f0682340 100644 --- a/xbmc/pvr/windows/GUIWindowPVRGuide.h +++ b/xbmc/pvr/windows/GUIWindowPVRGuide.h @@ -21,6 +21,7 @@ #include <atomic> #include <memory> +#include "threads/Event.h" #include "threads/Thread.h" #include "GUIWindowPVRBase.h" @@ -99,7 +100,12 @@ namespace PVR virtual void Process(); + void DoRefresh(); + void Stop(); + private: CGUIWindowPVRGuide *m_pGuideWindow; + CEvent m_ready; + CEvent m_done; }; } |