Browse files

[pvr] make all livetv views available to the user earlier (as soon as…

… channels are fetched from the backend and before epg is loaded from the db) by changing the pvr/epg manager startup logic
  • Loading branch information...
1 parent a773d7f commit 85e8a0db876ba43923832e007c8f134a769f223b @nemphys committed Dec 27, 2012
View
66 xbmc/epg/EpgContainer.cpp
@@ -52,6 +52,7 @@ CEpgContainer::CEpgContainer(void) :
m_iNextEpgId = 0;
m_bPreventUpdates = false;
m_updateEvent.Reset();
+ m_bStarted = false;
m_bLoaded = false;
m_bHasPendingUpdates = false;
}
@@ -73,6 +74,12 @@ void CEpgContainer::Unload(void)
Clear(false);
}
+bool CEpgContainer::IsStarted(void) const
+{
+ CSingleLock lock(m_critSection);
+ return m_bStarted;
+}
+
unsigned int CEpgContainer::NextEpgId(void)
{
CSingleLock lock(m_critSection);
@@ -99,6 +106,7 @@ void CEpgContainer::Clear(bool bClearDb /* = false */)
}
m_epgs.clear();
m_iNextEpgUpdate = 0;
+ m_bStarted = false;
m_bIsInitialising = true;
m_iNextEpgId = 0;
}
@@ -124,25 +132,35 @@ void CEpgContainer::Start(void)
{
Stop();
- CSingleLock lock(m_critSection);
+ {
+ CSingleLock lock(m_critSection);
- if (!m_database.IsOpen())
- m_database.Open();
+ if (!m_database.IsOpen())
+ m_database.Open();
- m_bIsInitialising = true;
- m_bStop = false;
- g_guiSettings.RegisterObserver(this);
- LoadSettings();
+ m_bIsInitialising = true;
+ m_bStop = false;
+ g_guiSettings.RegisterObserver(this);
+ LoadSettings();
- m_iNextEpgUpdate = 0;
- m_iNextEpgActiveTagCheck = 0;
+ m_iNextEpgUpdate = 0;
+ m_iNextEpgActiveTagCheck = 0;
+ }
LoadFromDB();
- CheckPlayingEvents();
- Create();
- SetPriority(-1);
- CLog::Log(LOGNOTICE, "%s - EPG thread started", __FUNCTION__);
+ CSingleLock lock(m_critSection);
+ if (!m_bStop)
+ {
+ CheckPlayingEvents();
+
+ Create();
+ SetPriority(-1);
+
+ m_bStarted = true;
+
+ CLog::Log(LOGNOTICE, "%s - EPG thread started", __FUNCTION__);
+ }
}
bool CEpgContainer::Stop(void)
@@ -152,6 +170,9 @@ bool CEpgContainer::Stop(void)
if (m_database.IsOpen())
m_database.Close();
+ CSingleLock lock(m_critSection);
+ m_bStarted = false;
+
return true;
}
@@ -169,6 +190,8 @@ void CEpgContainer::Notify(const Observable &obs, const ObservableMessage msg)
void CEpgContainer::LoadFromDB(void)
{
+ CSingleLock lock(m_critSection);
+
if (m_bLoaded || m_bIgnoreDbForClient)
return;
@@ -188,14 +211,17 @@ void CEpgContainer::LoadFromDB(void)
for (map<unsigned int, CEpg *>::iterator it = m_epgs.begin(); it != m_epgs.end(); it++)
{
+ if (m_bStop)
+ break;
UpdateProgressDialog(++iCounter, m_epgs.size(), it->second->Name());
+ lock.Leave();
it->second->Load();
+ lock.Enter();
}
CloseProgressDialog();
}
- CSingleLock lock(m_critSection);
m_bLoaded = bLoaded;
}
@@ -237,7 +263,7 @@ void CEpgContainer::Process(void)
}
/* update the EPG */
- if (!InterruptUpdate() && bUpdateEpg && UpdateEPG())
+ if (!InterruptUpdate() && bUpdateEpg && g_PVRManager.EpgsCreated() && UpdateEPG())
m_bIsInitialising = false;
/* clean up old entries */
@@ -325,7 +351,6 @@ CEpg *CEpgContainer::CreateChannelEpg(CPVRChannelPtr channel)
return NULL;
WaitForUpdateFinish(true);
- CSingleLock lock(m_critSection);
LoadFromDB();
CEpg *epg(NULL);
@@ -336,15 +361,20 @@ CEpg *CEpgContainer::CreateChannelEpg(CPVRChannelPtr channel)
{
channel->SetEpgID(NextEpgId());
epg = new CEpg(channel, false);
+
+ CSingleLock lock(m_critSection);
m_epgs.insert(make_pair((unsigned int)epg->EpgID(), epg));
SetChanged();
epg->RegisterObserver(this);
}
epg->SetChannel(channel);
- m_bPreventUpdates = false;
- CDateTime::GetCurrentDateTime().GetAsUTCDateTime().GetAsTime(m_iNextEpgUpdate);
+ {
+ CSingleLock lock(m_critSection);
+ m_bPreventUpdates = false;
+ CDateTime::GetCurrentDateTime().GetAsUTCDateTime().GetAsTime(m_iNextEpgUpdate);
+ }
NotifyObservers(ObservableMessageEpgContainer);
View
7 xbmc/epg/EpgContainer.h
@@ -93,6 +93,12 @@ namespace EPG
virtual void Reset(void) { Clear(true); }
/*!
+ * @brief Check whether the EpgContainer has fully started.
+ * @return True if started, false otherwise.
+ */
+ bool IsStarted(void) const;
+
+ /*!
* @brief Delete an EPG table from this container.
* @param epg The table to delete.
* @param bDeleteFromDatabase Delete this table from the database too if true.
@@ -267,6 +273,7 @@ namespace EPG
//@{
bool m_bIsUpdating; /*!< true while an update is running */
bool m_bIsInitialising; /*!< true while the epg manager hasn't loaded all tables */
+ bool m_bStarted; /*!< true if EpgContainer has fully started */
bool m_bLoaded; /*!< true after epg data is initially loaded from the database */
bool m_bPreventUpdates; /*!< true to prevent EPG updates */
bool m_bHasPendingUpdates; /*!< true if there are manual updates pending */
View
35 xbmc/pvr/PVRManager.cpp
@@ -70,6 +70,7 @@ CPVRManager::CPVRManager(void) :
m_currentFile(NULL),
m_database(NULL),
m_bFirstStart(true),
+ m_bEpgsCreated(false),
m_progressHandle(NULL),
m_managerState(ManagerStateStopped),
m_bOpenPVRWindow(false)
@@ -197,6 +198,7 @@ void CPVRManager::Cleanup(void)
m_bIsSwitchingChannels = false;
m_outdatedAddons.clear();
m_bOpenPVRWindow = false;
+ m_bEpgsCreated = false;
for (unsigned int iJobPtr = 0; iJobPtr < m_pendingUpdates.size(); iJobPtr++)
delete m_pendingUpdates.at(iJobPtr);
@@ -822,6 +824,11 @@ CPVRChannelGroupPtr CPVRManager::GetPlayingGroup(bool bRadio /* = false */)
return CPVRChannelGroupPtr();
}
+bool CPVREpgsCreateJob::DoWork(void)
+{
+ return g_PVRManager.CreateChannelEpgs();
+}
+
bool CPVRRecordingsUpdateJob::DoWork(void)
{
g_PVRRecordings->Update();
@@ -1171,6 +1178,12 @@ bool CPVRManager::IsStarted(void) const
return GetState() == ManagerStateStarted;
}
+bool CPVRManager::EpgsCreated(void) const
+{
+ CSingleLock lock(m_critSection);
+ return m_bEpgsCreated;
+}
+
bool CPVRManager::IsPlayingTV(void) const
{
return IsStarted() && m_addons && m_addons->IsPlayingTV();
@@ -1219,6 +1232,18 @@ bool CPVRManager::IsJobPending(const char *strJobName) const
return bReturn;
}
+void CPVRManager::TriggerEpgsCreate(void)
+{
+ CSingleLock lock(m_critSectionTriggers);
+ if (IsJobPending("pvr-create-epgs"))
+ return;
+
+ m_pendingUpdates.push_back(new CPVREpgsCreateJob());
+
+ lock.Leave();
+ m_triggerEvent.Set();
+}
+
void CPVRManager::TriggerRecordingsUpdate(void)
{
CSingleLock lock(m_critSectionTriggers);
@@ -1319,3 +1344,13 @@ bool CPVRChannelSwitchJob::DoWork(void)
return true;
}
+
+bool CPVRManager::CreateChannelEpgs(void)
+{
+ if (EpgsCreated())
+ return true;
+
+ CSingleLock lock(m_critSection);
+ m_bEpgsCreated = m_channelGroups->CreateChannelEpgs();
+ return m_bEpgsCreated;
+}
View
28 xbmc/pvr/PVRManager.h
@@ -229,6 +229,12 @@ namespace PVR
bool IsStarted(void) const;
/*!
+ * @brief Check whether EPG tags for channels have been created.
+ * @return True if EPG tags have been created, false otherwise.
+ */
+ bool EpgsCreated(void) const;
+
+ /*!
* @brief Reset the playing EPG tag.
*/
void ResetPlayingTag(void);
@@ -312,6 +318,11 @@ namespace PVR
CPVRChannelGroupPtr GetPlayingGroup(bool bRadio = false);
/*!
+ * @brief Let the background thread create epg tags for all channels.
+ */
+ void TriggerEpgsCreate(void);
+
+ /*!
* @brief Let the background thread update the recordings list.
*/
void TriggerRecordingsUpdate(void);
@@ -467,6 +478,12 @@ namespace PVR
*/
bool SetWakeupCommand(void);
+ /*!
+ * @brief Creat EPG tags for all channels in internal channel groups
+ * @return True if EPG tags where created successfully, false otherwise
+ */
+ bool CreateChannelEpgs(void);
+
protected:
/*!
* @brief PVR update and control thread.
@@ -568,6 +585,7 @@ namespace PVR
CCriticalSection m_critSection; /*!< critical section for all changes to this class, except for changes to triggers */
bool m_bFirstStart; /*!< true when the PVR manager was started first, false otherwise */
bool m_bIsSwitchingChannels; /*!< true while switching channels */
+ bool m_bEpgsCreated; /*!< true if epg data for channels has been created */
CGUIDialogProgressBarHandle * m_progressHandle; /*!< progress dialog that is displayed while the pvrmanager is loading */
CCriticalSection m_managerStateMutex;
@@ -577,6 +595,16 @@ namespace PVR
std::map<std::string, std::string> m_outdatedAddons;
};
+ class CPVREpgsCreateJob : public CJob
+ {
+ public:
+ CPVREpgsCreateJob(void) {}
+ virtual ~CPVREpgsCreateJob() {}
+ virtual const char *GetType() const { return "pvr-create-epgs"; }
+
+ virtual bool DoWork();
+ };
+
class CPVRRecordingsUpdateJob : public CJob
{
public:
View
6 xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -1185,3 +1185,9 @@ bool CPVRChannelGroup::IsSelectedGroup(void) const
CSingleLock lock(m_critSection);
return m_bSelectedGroup;
}
+
+bool CPVRChannelGroup::CreateChannelEpgs(bool bForce /* = false */)
+{
+ /* used only by internal channel groups */
+ return true;
+}
View
7 xbmc/pvr/channels/PVRChannelGroup.h
@@ -403,6 +403,13 @@ namespace PVR
bool RemoveDeletedChannels(const CPVRChannelGroup &channels);
/*!
+ * @brief Create an EPG table for each channel.
+ * @brief bForce Create the tables, even if they already have been created before.
+ * @return True if all tables were created successfully, false otherwise.
+ */
+ virtual bool CreateChannelEpgs(bool bForce = false);
+
+ /*!
* @brief Remove invalid channels from this container.
*/
void RemoveInvalidChannels(void);
View
4 xbmc/pvr/channels/PVRChannelGroupInternal.cpp
@@ -61,7 +61,7 @@ bool CPVRChannelGroupInternal::Load(void)
if (CPVRChannelGroup::Load())
{
UpdateChannelPaths();
- CreateChannelEpgs();
+ g_PVRManager.TriggerEpgsCreate();
return true;
}
@@ -364,6 +364,8 @@ void CPVRChannelGroupInternal::CreateChannelEpg(CPVRChannelPtr channel, bool bFo
bool CPVRChannelGroupInternal::CreateChannelEpgs(bool bForce /* = false */)
{
+ if (!g_EpgContainer.IsStarted())
+ return false;
{
CSingleLock lock(m_critSection);
for (unsigned int iChannelPtr = 0; iChannelPtr < m_members.size(); iChannelPtr++)
View
13 xbmc/pvr/channels/PVRChannelGroups.cpp
@@ -520,3 +520,16 @@ void CPVRChannelGroups::FillGroupsGUI(int iWindowId, int iControlId) const
CGUIMessage msgSel(GUI_MSG_ITEM_SELECT, iWindowId, iControlId, iSelectedGroupPtr);
g_windowManager.SendMessage(msgSel);
}
+
+bool CPVRChannelGroups::CreateChannelEpgs(void)
+{
+ bool bReturn(false);
+ CSingleLock lock(m_critSection);
+ for (std::vector<CPVRChannelGroupPtr>::iterator it = m_groups.begin(); it != m_groups.end(); it++)
+ {
+ /* Only create EPGs for the internatl groups */
+ if ((*it)->IsInternalGroup())
+ bReturn = (*it)->CreateChannelEpgs();
+ }
+ return bReturn;
+}
View
6 xbmc/pvr/channels/PVRChannelGroups.h
@@ -163,6 +163,12 @@ namespace PVR
bool DeleteGroup(const CPVRChannelGroup &group);
/*!
+ * @brief Create EPG tags for all channels of the internal group.
+ * @return True if EPG tags where created successfully, false if not.
+ */
+ bool CreateChannelEpgs(void);
+
+ /*!
* @brief Remove a channel from all non-system groups.
* @param channel The channel to remove.
*/
View
7 xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -282,3 +282,10 @@ bool CPVRChannelGroupsContainer::CreateChannel(const CPVRChannel &channel)
{
return GetGroupAll(channel.IsRadio())->AddNewChannel(channel);
}
+
+
+bool CPVRChannelGroupsContainer::CreateChannelEpgs(void)
+{
+ return m_groupsRadio->CreateChannelEpgs() &&
+ m_groupsTV->CreateChannelEpgs();
+}
View
6 xbmc/pvr/channels/PVRChannelGroupsContainer.h
@@ -182,6 +182,12 @@ namespace PVR
bool CreateChannel(const CPVRChannel &channel);
+ /*!
+ * @brief Create EPG tags for channels in all internal channel groups.
+ * @return True if EPG tags were created succesfully.
+ */
+ bool CreateChannelEpgs(void);
+
protected:
/*!
* @brief Update the contents of all the groups in this container.

0 comments on commit 85e8a0d

Please sign in to comment.