aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2017-03-19 22:48:52 +0100
committerKai Sommerfeld <kai.sommerfeld@gmx.com>2017-03-26 21:02:00 +0200
commit3bcba5bb2a8956ff6254f1c8308fd3215966ce84 (patch)
tree1c6822a3d2924d5e142ac48d315d6c172a2570b0
parentcbd96778cf947793f709c0e8508a085f5f101f2e (diff)
[PVR] Guide window: Implement asynchronous channel group switching.
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp61
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.h6
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;
};
}