summaryrefslogtreecommitdiff
path: root/extensions/timers.c
blob: 4f81b2a4fed2ec6a9089ff42241980702011ba87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "timers.h"
#include "../services/epgsearch.h"
#include "../services/remotetimers.h"

static int CompareTimers(const void *a, const void *b) {
    return (*(const cTimer **)a)->Compare(**(const cTimer **)b);
}

cGlobalSortedTimers::cGlobalSortedTimers(int timerCount, bool forceRefresh) : cVector<const cTimer*>(timerCount) {
    static bool initial = true;
    static cRemoteTimerRefresh *remoteTimerRefresh = NULL;
    localTimer = NULL;

    if (forceRefresh)
        initial = true;
    //check if remotetimers plugin is available
    static cPlugin* pRemoteTimers = cPluginManager::GetPlugin("remotetimers");

#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
    LOCK_TIMERS_READ;
    LOCK_SCHEDULES_READ;
    const cTimers* timers = Timers;
    const cSchedules* schedules = Schedules;
#else
    const cTimers* timers = &Timers;
    cSchedulesLock schedulesLock;
    const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
#endif
    
    if (pRemoteTimers && initial) {
        cString errorMsg;
        pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg);
        initial = false;
    }

    for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
        if (Timer->HasFlags(tfActive))
            Append(Timer);
    }

    //if remotetimers plugin is available, take timers also from him
    if (pRemoteTimers) {
        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);
        }
    }
  
    Sort(CompareTimers);
    
    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;
                    }
                }
            }
        }
    }

    if (pRemoteTimers && (remoteTimerRefresh == NULL))
        remoteTimerRefresh = new cRemoteTimerRefresh();
}

cGlobalSortedTimers::~cGlobalSortedTimers(void) {
    if (localTimer) {
        delete[] localTimer;
    }
}

bool cGlobalSortedTimers::IsRemoteTimer(int i) {
    if (!localTimer)
        return true;
    if (i >= Size())
        return true;
    return !(localTimer[i]);
}


int cGlobalSortedTimers::NumTimerConfilicts(void) {
    int numConflicts = 0;
    cPlugin *p = cPluginManager::GetPlugin("epgsearch");
    if (p) {
        Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0;
        if (serviceData) {
            serviceData->nextConflict = 0;
            serviceData->relevantConflicts = 0;
            serviceData->totalConflicts = 0;
            p->Service("Epgsearch-lastconflictinfo-v1.0", serviceData);
            if (serviceData->relevantConflicts > 0) {
                numConflicts = serviceData->relevantConflicts;
            }
            delete serviceData;
        }
    }
    return numConflicts;
}

cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") {
    Start();
}

cRemoteTimerRefresh::~cRemoteTimerRefresh(void) {
    Cancel(-1);
    while (Active())
        cCondWait::SleepMs(10);
}

void cRemoteTimerRefresh::Action(void) {    
#define REFESH_INTERVALL_MS 30000
    while (Running()) {
        cCondWait::SleepMs(REFESH_INTERVALL_MS);
        // make sure that no timer is currently being edited
        if (!cOsd::IsOpen()) {
            cGlobalSortedTimers(true);
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
            LOCK_TIMERS_WRITE;
            Timers->SetModified();
#else
            Timers.SetModified();
#endif
        }
    }
}