#include "globaltimers.h" #include "../services/epgsearch.h" #include "../services/remotetimers.h" #include "../services/epgtimer.h" static int CompareTimers(const void *a, const void *b) { return (*(const cTimer **)a)->Compare(**(const cTimer **)b); } bool cGlobalTimers::initial = true; cRemoteTimerRefresh *cGlobalTimers::remoteTimerRefresh = NULL; cGlobalTimers::cGlobalTimers(void) : cVector<const cTimer*>(0) { pEpg2Vdr = cPluginManager::GetPlugin("epg2vdr"); pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); pEpgSearch = cPluginManager::GetPlugin("epgsearch"); localTimer = NULL; isEpg2VdrTimers = false; } cGlobalTimers::~cGlobalTimers(void) { if (localTimer) { delete[] localTimer; } ClearTimers(); } void cGlobalTimers::LoadTimers(void) { isEpg2VdrTimers = false; bool epg2vdrOk = false; if (pEpg2Vdr) { epg2vdrOk = SetEpg2VdrTimers(); } if (!epg2vdrOk) { SetLocalTimers(); if (pRemoteTimers) { SetRemoteTimers(initial); } } initial = false; } void cGlobalTimers::SortTimers(void) { Sort(CompareTimers); } void cGlobalTimers::MarkLocalTimers(void) { if (isEpg2VdrTimers) return; if (localTimer) { delete[] localTimer; localTimer = NULL; } #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) LOCK_TIMERS_READ; const cTimers* timers = Timers; #else const cTimers* timers = &Timers; #endif int numTimers = Size(); if (numTimers > 0) { localTimer = new bool[numTimers]; for (int i=0; i < numTimers; i++) { if (!pRemoteTimers) { localTimer[i] = true; } else { localTimer[i] = false; for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) { if (Timer == At(i)) { localTimer[i] = true; break; } } } } } } void cGlobalTimers::SetLocalTimers(void) { #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) LOCK_TIMERS_READ; const cTimers* timers = Timers; #else const cTimers* timers = &Timers; #endif for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) { if (Timer->HasFlags(tfActive)) Append(Timer); } } void cGlobalTimers::SetRemoteTimers(bool initial) { if (initial) { cString errorMsg; pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg); } #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) LOCK_SCHEDULES_READ; const cSchedules* schedules = Schedules; #else cSchedulesLock schedulesLock; const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); #endif cTimer* remoteTimer = NULL; while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) { remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current if (remoteTimer->HasFlags(tfActive)) Append(remoteTimer); } } bool cGlobalTimers::SetEpg2VdrTimers(void) { bool ok = false; cEpgTimer_Service_V1 data; if (pEpg2Vdr->Service(EPG2VDR_TIMER_SERVICE, &data)) { for (std::list<cEpgTimer_Interface_V1*>::iterator it = data.epgTimers.begin(); it != data.epgTimers.end(); ++it) { ok = true; isEpg2VdrTimers = true; if ((*it)->HasFlags(tfActive)) { Append(*it); } } } return ok; } int cGlobalTimers::NumTimerConfilicts(void) { int numConflicts = 0; if (pEpgSearch) { Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0; if (serviceData) { serviceData->nextConflict = 0; serviceData->relevantConflicts = 0; serviceData->totalConflicts = 0; pEpgSearch->Service("Epgsearch-lastconflictinfo-v1.0", serviceData); if (serviceData->relevantConflicts > 0) { numConflicts = serviceData->relevantConflicts; } delete serviceData; } } return numConflicts; } bool cGlobalTimers::IsRemoteTimer(int i) { if (isEpg2VdrTimers) { cEpgTimer_Interface_V1* epgTimer; if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i))) return !epgTimer->isLocal(); else return false; } if (!localTimer) return true; if (i >= Size()) return true; return !(localTimer[i]); } const char* cGlobalTimers::RemoteHost(int i) { if (isEpg2VdrTimers) { cEpgTimer_Interface_V1* epgTimer; if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i))) return epgTimer->VdrName(); } return ""; } bool cGlobalTimers::IsRecording(const cRecording *rec) { if (!rec || !rec->Name()) return false; std::string recName = rec->Name(); int size = Size(); for (int i=0; i<size; i++) { const cTimer *t = At(i); const char *timerFile = t->File(); if (!t->Matches() || !timerFile) continue; if (recName.find(timerFile) != std::string::npos) return true; } return false; } void cGlobalTimers::ClearTimers(void) { if (isEpg2VdrTimers) { int size = Size(); for (int i=0; i<size; i++) { delete At(i); } } Clear(); } void cGlobalTimers::StartRefreshThread(void) { if (remoteTimerRefresh == NULL) { remoteTimerRefresh = new cRemoteTimerRefresh(); } } void cGlobalTimers::StopRefreshThread(void) { if (!remoteTimerRefresh) return; delete remoteTimerRefresh; remoteTimerRefresh = NULL; initial = true; } /************************************************************************* * cRemoteTimerRefresh *************************************************************************/ cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") { pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); if (pRemoteTimers) Start(); } cRemoteTimerRefresh::~cRemoteTimerRefresh(void) { Cancel(-1); while (Active()) cCondWait::SleepMs(10); } void cRemoteTimerRefresh::Action(void) { #define REFESH_INTERVALL_MS 30000 int sleepSlice = 1000; int slept = 0; while (Running()) { while (Running() && slept < REFESH_INTERVALL_MS) { cCondWait::SleepMs(sleepSlice); slept += sleepSlice; } slept = 0; // make sure that no timer is currently being edited if (!cOsd::IsOpen() && Running()) { cString errorMsg; pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301) LOCK_TIMERS_WRITE; Timers->SetModified(); #else Timers.SetModified(); #endif } } }