summaryrefslogtreecommitdiff
path: root/extensions/globaltimers.c
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/globaltimers.c')
-rw-r--r--extensions/globaltimers.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/extensions/globaltimers.c b/extensions/globaltimers.c
new file mode 100644
index 0000000..6e7263e
--- /dev/null
+++ b/extensions/globaltimers.c
@@ -0,0 +1,233 @@
+#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) {
+ uint64_t start = cTimeMs::Now();
+ isEpg2VdrTimers = false;
+ bool epg2vdrOk = false;
+ if (pEpg2Vdr) {
+ epg2vdrOk = SetEpg2VdrTimers();
+ }
+ if (!epg2vdrOk) {
+ SetLocalTimers();
+ if (pRemoteTimers) {
+ SetRemoteTimers(initial);
+ }
+ }
+ esyslog("skindesigner: loaded %d timers, needed %d ms", Size(), cTimeMs::Now() - start);
+ 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 "";
+}
+
+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
+ }
+ }
+}