added VDR 2.3.1 compatibility

This commit is contained in:
louis 2016-03-13 16:02:26 +01:00
parent ef69fa6b36
commit b40f8c014e
15 changed files with 318 additions and 119 deletions

View File

@ -123,7 +123,7 @@ public:
cSDPluginManager *plgManager = NULL; cSDPluginManager *plgManager = NULL;
cFontManager *fontManager = NULL; cFontManager *fontManager = NULL;
cImageCache *imgCache = NULL; cImageCache *imgCache = NULL;
cRecordingsFolderInfo recFolderInfo(Recordings); cRecordingsFolderInfo recFolderInfo;
#else #else
extern cDesignerConfig config; extern cDesignerConfig config;
extern cSDPluginManager *plgManager; extern cSDPluginManager *plgManager;

View File

@ -51,36 +51,36 @@ cArea::cArea(const cArea &other) {
blinking = false; blinking = false;
scrollFunc = NULL; scrollFunc = NULL;
for (cFunction *func = other.functions.First(); func; func = other.functions.Next(func)) { for (const cFunction *func = other.functions.First(); func; func = other.functions.Next(func)) {
if (cFuncFill *f = dynamic_cast<cFuncFill*>(func)) { if (cFuncFill *f = dynamic_cast<cFuncFill*>((cFunction*)func)) {
cFuncFill *fFill = new cFuncFill(*f); cFuncFill *fFill = new cFuncFill(*f);
fFill->SetOwner(this); fFill->SetOwner(this);
functions.Add(fFill); functions.Add(fFill);
} else if (cFuncDrawRectangle *f = dynamic_cast<cFuncDrawRectangle*>(func)) { } else if (cFuncDrawRectangle *f = dynamic_cast<cFuncDrawRectangle*>((cFunction*)func)) {
cFuncDrawRectangle *fDrawRect = new cFuncDrawRectangle(*f); cFuncDrawRectangle *fDrawRect = new cFuncDrawRectangle(*f);
fDrawRect->SetOwner(this); fDrawRect->SetOwner(this);
functions.Add(fDrawRect); functions.Add(fDrawRect);
} else if (cFuncDrawEllipse *f = dynamic_cast<cFuncDrawEllipse*>(func)) { } else if (cFuncDrawEllipse *f = dynamic_cast<cFuncDrawEllipse*>((cFunction*)func)) {
cFuncDrawEllipse *fDrawEllipse = new cFuncDrawEllipse(*f); cFuncDrawEllipse *fDrawEllipse = new cFuncDrawEllipse(*f);
fDrawEllipse->SetOwner(this); fDrawEllipse->SetOwner(this);
functions.Add(fDrawEllipse); functions.Add(fDrawEllipse);
} else if (cFuncDrawSlope *f = dynamic_cast<cFuncDrawSlope*>(func)) { } else if (cFuncDrawSlope *f = dynamic_cast<cFuncDrawSlope*>((cFunction*)func)) {
cFuncDrawSlope *fDrawSlope = new cFuncDrawSlope(*f); cFuncDrawSlope *fDrawSlope = new cFuncDrawSlope(*f);
fDrawSlope->SetOwner(this); fDrawSlope->SetOwner(this);
functions.Add(fDrawSlope); functions.Add(fDrawSlope);
} else if (cFuncDrawText *f = dynamic_cast<cFuncDrawText*>(func)) { } else if (cFuncDrawText *f = dynamic_cast<cFuncDrawText*>((cFunction*)func)) {
cFuncDrawText *fDrawText = new cFuncDrawText(*f); cFuncDrawText *fDrawText = new cFuncDrawText(*f);
fDrawText->SetOwner(this); fDrawText->SetOwner(this);
functions.Add(fDrawText); functions.Add(fDrawText);
} else if (cFuncDrawTextVertical *f = dynamic_cast<cFuncDrawTextVertical*>(func)) { } else if (cFuncDrawTextVertical *f = dynamic_cast<cFuncDrawTextVertical*>((cFunction*)func)) {
cFuncDrawTextVertical *fDrawTextVertical = new cFuncDrawTextVertical(*f); cFuncDrawTextVertical *fDrawTextVertical = new cFuncDrawTextVertical(*f);
fDrawTextVertical->SetOwner(this); fDrawTextVertical->SetOwner(this);
functions.Add(fDrawTextVertical); functions.Add(fDrawTextVertical);
} else if (cFuncDrawTextBox *f = dynamic_cast<cFuncDrawTextBox*>(func)) { } else if (cFuncDrawTextBox *f = dynamic_cast<cFuncDrawTextBox*>((cFunction*)func)) {
cFuncDrawTextBox *fDrawTextBox = new cFuncDrawTextBox(*f); cFuncDrawTextBox *fDrawTextBox = new cFuncDrawTextBox(*f);
fDrawTextBox->SetOwner(this); fDrawTextBox->SetOwner(this);
functions.Add(fDrawTextBox); functions.Add(fDrawTextBox);
} else if (cFuncDrawImage *f = dynamic_cast<cFuncDrawImage*>(func)) { } else if (cFuncDrawImage *f = dynamic_cast<cFuncDrawImage*>((cFunction*)func)) {
cFuncDrawImage *fDrawImage = new cFuncDrawImage(*f); cFuncDrawImage *fDrawImage = new cFuncDrawImage(*f);
fDrawImage->SetOwner(this); fDrawImage->SetOwner(this);
functions.Add(fDrawImage); functions.Add(fDrawImage);
@ -580,7 +580,7 @@ cAreaContainer::cAreaContainer(void) {
cAreaContainer::cAreaContainer(const cAreaContainer &other) { cAreaContainer::cAreaContainer(const cAreaContainer &other) {
globals = other.globals; globals = other.globals;
attribs = new cAreaContainerAttribs(*other.attribs); attribs = new cAreaContainerAttribs(*other.attribs);
for (cArea *area = other.areas.First(); area; area = other.areas.Next(area)) { for (const cArea *area = other.areas.First(); area; area = other.areas.Next(area)) {
cArea *a = new cArea(*area); cArea *a = new cArea(*area);
a->SetAreaContainer(this); a->SetAreaContainer(this);
areas.Add(a); areas.Add(a);

View File

@ -99,7 +99,7 @@ void cCond::Debug(void) {
if (compareValue >= 0) if (compareValue >= 0)
esyslog("skindesigner: compare value: %d", compareValue); esyslog("skindesigner: compare value: %d", compareValue);
if (compareStrValue) if (compareStrValue)
esyslog("skindesigner: compare string value: %d", compareStrValue); esyslog("skindesigner: compare string value: %s", compareStrValue);
} }
/****************************************************************** /******************************************************************
@ -117,7 +117,7 @@ cCondition::cCondition(const cCondition &other) {
globals = NULL; globals = NULL;
tokenContainer = NULL; tokenContainer = NULL;
loopInfo = NULL; loopInfo = NULL;
for (cCond *cond = other.conds.First(); cond; cond = other.conds.Next(cond)) for (const cCond *cond = other.conds.First(); cond; cond = other.conds.Next(cond))
conds.Add(new cCond(*cond)); conds.Add(new cCond(*cond));
} }
@ -468,7 +468,7 @@ cSummand::cSummand(const cSummand &other) {
if (other.summand) if (other.summand)
summand = strdup(other.summand); summand = strdup(other.summand);
positive = other.positive; positive = other.positive;
for (cFactor *fac = other.factors.First(); fac; fac = other.factors.Next(fac)) { for (const cFactor *fac = other.factors.First(); fac; fac = other.factors.Next(fac)) {
factors.Add(new cFactor(*fac)); factors.Add(new cFactor(*fac));
} }
} }
@ -490,13 +490,13 @@ void cSummand::Debug(void) {
else if (f->type == eFactorType::looptoken) else if (f->type == eFactorType::looptoken)
esyslog("skindesigner: LoopToken factor, index %d, %s", f->tokenIndex, link); esyslog("skindesigner: LoopToken factor, index %d, %s", f->tokenIndex, link);
else if (f->type == eFactorType::xref) else if (f->type == eFactorType::xref)
esyslog("skindesigner: posx reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncX()); esyslog("skindesigner: posx reference factor, %s, %p, %s, result: %d", f->funcRefName, f->funcRef, link, f->funcRef->FuncX());
else if (f->type == eFactorType::yref) else if (f->type == eFactorType::yref)
esyslog("skindesigner: posy reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncY()); esyslog("skindesigner: posy reference factor, %s, %p, %s, result: %d", f->funcRefName, f->funcRef, link, f->funcRef->FuncY());
else if (f->type == eFactorType::widthref) else if (f->type == eFactorType::widthref)
esyslog("skindesigner: width reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncWidth()); esyslog("skindesigner: width reference factor, %s, %p, %s, result: %d", f->funcRefName, f->funcRef, link, f->funcRef->FuncWidth());
else if (f->type == eFactorType::heightref) else if (f->type == eFactorType::heightref)
esyslog("skindesigner: height reference factor, %s, %p %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncHeight()); esyslog("skindesigner: height reference factor, %s, %p %s, result: %d", f->funcRefName, f->funcRef, link, f->funcRef->FuncHeight());
else if (f->type == eFactorType::areawidth) else if (f->type == eFactorType::areawidth)
esyslog("skindesigner: {areawidth} factor, %s", link); esyslog("skindesigner: {areawidth} factor, %s", link);
else if (f->type == eFactorType::areaheight) else if (f->type == eFactorType::areaheight)
@ -531,7 +531,7 @@ cNumericExpr::cNumericExpr(const cNumericExpr &other) {
horizontal = other.horizontal; horizontal = other.horizontal;
value = other.value; value = other.value;
dynamic = other.dynamic; dynamic = other.dynamic;
for (cSummand *s = other.summands.First(); s; s = other.summands.Next(s)) { for (const cSummand *s = other.summands.First(); s; s = other.summands.Next(s)) {
summands.Add(new cSummand(*s)); summands.Add(new cSummand(*s));
} }
} }
@ -1079,7 +1079,7 @@ cTextExpr::cTextExpr(const cTextExpr &other) {
expr = strdup(other.expr); expr = strdup(other.expr);
tokenContainer = NULL; tokenContainer = NULL;
loopInfo = NULL; loopInfo = NULL;
for (cTextToken* t = other.textTokens.First(); t; t = other.textTokens.Next(t)) { for (const cTextToken* t = other.textTokens.First(); t; t = other.textTokens.Next(t)) {
textTokens.Add(new cTextToken(*t)); textTokens.Add(new cTextToken(*t));
} }
} }

View File

@ -797,10 +797,14 @@ bool cCeMenuSchedules::Parse(bool forced) {
if (menuCat == mcScheduleNow || menuCat == mcScheduleNext) { if (menuCat == mcScheduleNow || menuCat == mcScheduleNext) {
int eventsAvailable = 0; int eventsAvailable = 0;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock; cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock); const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL; #endif
schedule = schedules->GetSchedule(channel); const cSchedule *schedule = schedules->GetSchedule(channel);
if (schedule) { if (schedule) {
for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) { for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) {
eventsAvailable++; eventsAvailable++;
@ -917,10 +921,14 @@ bool cLeMenuChannels::Parse(bool forced) {
} }
//current schedule //current schedule
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock; cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock); const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL; #endif
schedule = schedules->GetSchedule(channel); const cSchedule *schedule = schedules->GetSchedule(channel);
if (schedule) { if (schedule) {
const cEvent *presentEvent = schedule->GetPresentEvent(); const cEvent *presentEvent = schedule->GetPresentEvent();
if (presentEvent) { if (presentEvent) {
@ -1046,10 +1054,14 @@ bool cCeMenuChannels::Parse(bool forced) {
tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isTerr, source->IsTerr(source->Code())); tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isTerr, source->IsTerr(source->Code()));
} }
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock; cSchedulesLock schedulesLock;
const cSchedules *schedules = cSchedules::Schedules(schedulesLock); const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
const cSchedule *schedule = NULL; #endif
schedule = schedules->GetSchedule(channel); const cSchedule *schedule = schedules->GetSchedule(channel);
if (schedule) { if (schedule) {
const cEvent *presentEvent = schedule->GetPresentEvent(); const cEvent *presentEvent = schedule->GetPresentEvent();
if (presentEvent) { if (presentEvent) {
@ -1484,7 +1496,13 @@ bool cLeMenuRecordings::Parse(bool forced) {
cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName); cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName);
delete[] folderName; delete[] folderName;
if (folderInfo) { if (folderInfo) {
cRecording *newestRec = Recordings.GetByName(*folderInfo->LatestFileName); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_RECORDINGS_READ;
const cRecordings* recordings = Recordings;
#else
cRecordings* recordings = &Recordings;
#endif
const cRecording *newestRec = recordings->GetByName(*folderInfo->LatestFileName);
if (newestRec) { if (newestRec) {
usedRecording = newestRec; usedRecording = newestRec;
} }
@ -1724,7 +1742,13 @@ bool cCeMenuRecordings::Parse(bool forced) {
if (isFolder) { if (isFolder) {
cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName.str().c_str()); cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName.str().c_str());
if (folderInfo) { if (folderInfo) {
cRecording *newestRec = Recordings.GetByName(*folderInfo->LatestFileName); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_RECORDINGS_READ;
const cRecordings* recordings = Recordings;
#else
cRecordings* recordings = &Recordings;
#endif
const cRecording *newestRec = recordings->GetByName(*folderInfo->LatestFileName);
if (newestRec) { if (newestRec) {
usedRecording = newestRec; usedRecording = newestRec;
} }

View File

@ -353,7 +353,13 @@ bool cViewDetailEpg::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::year, sStartTime->tm_year + 1900); tokenContainer->AddIntToken((int)eDmDetailedEpgIT::year, sStartTime->tm_year + 1900);
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::daynumeric, sStartTime->tm_mday); tokenContainer->AddIntToken((int)eDmDetailedEpgIT::daynumeric, sStartTime->tm_mday);
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::month, sStartTime->tm_mon+1); tokenContainer->AddIntToken((int)eDmDetailedEpgIT::month, sStartTime->tm_mon+1);
const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(event->ChannelID());
if (channel) { if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedEpgST::channelname, channel->Name()); tokenContainer->AddStringToken((int)eDmDetailedEpgST::channelname, channel->Name());
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::channelnumber, channel->Number()); tokenContainer->AddIntToken((int)eDmDetailedEpgIT::channelnumber, channel->Number());
@ -434,7 +440,13 @@ int cViewDetailEpg::NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearch
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
time_t eventStart = event->StartTime(); time_t eventStart = event->StartTime();
time_t rerunStart = r->event->StartTime(); time_t rerunStart = r->event->StartTime();
cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(r->event->ChannelID(), true, true);
//check for identical event //check for identical event
if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
continue; continue;
@ -463,7 +475,13 @@ void cViewDetailEpg::SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearc
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
time_t eventStart = event->StartTime(); time_t eventStart = event->StartTime();
time_t rerunStart = r->event->StartTime(); time_t rerunStart = r->event->StartTime();
cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(r->event->ChannelID(), true, true);
//check for identical event //check for identical event
if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
continue; continue;
@ -792,7 +810,13 @@ void cViewDetailRec::SetRecInfos(void) {
const cRecordingInfo *info = recording->Info(); const cRecordingInfo *info = recording->Info();
if (info) { if (info) {
cChannel *channel = Channels.GetByChannelID(info->ChannelID()); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(info->ChannelID());
if (channel) { if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, channel->Name()); tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, *channel->GetChannelID().ToString()); tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, *channel->GetChannelID().ToString());

View File

@ -406,7 +406,12 @@ void cViewMenu::SetChannelHeader(const cEvent *event) {
if (!event) if (!event)
return; return;
if (menuChange && menuCat == mcSchedule) { if (menuChange && menuCat == mcSchedule) {
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(event->ChannelID());
#else
const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); const cChannel *channel = Channels.GetByChannelID(event->ChannelID());
#endif
if (channel) if (channel)
activeSubview->SetChannel(channel); activeSubview->SetChannel(channel);
} }

View File

@ -39,10 +39,10 @@ cViewElement::cViewElement(const cViewElement &other) {
tokenContainer = NULL; tokenContainer = NULL;
attribs = new cViewElementAttribs(*other.attribs); attribs = new cViewElementAttribs(*other.attribs);
for (cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) { for (const cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) {
if (cArea *a = dynamic_cast<cArea*>(node)) { if (cArea *a = dynamic_cast<cArea*>((cAreaNode*)node)) {
areaNodes.Add(new cArea(*a)); areaNodes.Add(new cArea(*a));
} else if (cAreaContainer *ac = dynamic_cast<cAreaContainer*>(node)) { } else if (cAreaContainer *ac = dynamic_cast<cAreaContainer*>((cAreaNode*)node)) {
areaNodes.Add(new cAreaContainer(*ac)); areaNodes.Add(new cAreaContainer(*ac));
} }
} }

View File

@ -287,18 +287,27 @@ bool cVeDevices::Parse(bool forced) {
else else
deviceLiveTV = primaryDevice->DeviceNumber(); deviceLiveTV = primaryDevice->DeviceNumber();
} }
//check currently recording devices // check currently recording devices
for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { // BLOCK for LOCK_TIMERS_READ scope !!
if (!timer->Recording()) { {
continue; #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
} LOCK_TIMERS_READ;
if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(timer)) { const cTimers* timers = Timers;
const cDevice *recDevice = RecordControl->Device(); #else
if (recDevice) { const cTimers* timers = &Timers;
mutexDevices.Lock(); #endif
if (recDevices) for (const cTimer *timer = timers->First(); timer; timer = timers->Next(timer)) {
recDevices[recDevice->DeviceNumber()] = true; if (!timer->Recording()) {
mutexDevices.Unlock(); continue;
}
if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(timer)) {
const cDevice *recDevice = RecordControl->Device();
if (recDevice) {
mutexDevices.Lock();
if (recDevices)
recDevices[recDevice->DeviceNumber()] = true;
mutexDevices.Unlock();
}
} }
} }
} }

View File

@ -91,9 +91,16 @@ void cVeDcChannelGroup::Set(const cChannel *c) {
} }
const char *cVeDcChannelGroup::GetChannelSep(const cChannel *c, bool prev) { const char *cVeDcChannelGroup::GetChannelSep(const cChannel *c, bool prev) {
const cChannel *sep = prev ? Channels.Prev(c) : #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
Channels.Next(c); LOCK_CHANNELS_READ;
for (; sep; (prev)?(sep = Channels.Prev(sep)):(sep = Channels.Next(sep))) { const cChannels* channels = Channels;
#else
const cChannels* channels = &Channels;
#endif
const cChannel *sep = prev ? channels->Prev(c) :
channels->Next(c);
for (; sep; (prev)?(sep = channels->Prev(sep)):(sep = channels->Next(sep))) {
if (sep->GroupSep()) { if (sep->GroupSep()) {
return sep->Name(); return sep->Name();
} }
@ -169,7 +176,17 @@ void cVeDcEpgInfo::Close(void) {
bool cVeDcEpgInfo::EventHasTimer(const cEvent *e) { bool cVeDcEpgInfo::EventHasTimer(const cEvent *e) {
if (!e) return false; if (!e) return false;
cGlobalSortedTimers SortedTimers;// local and remote timers int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
bool hasTimer = e->HasTimer(); bool hasTimer = e->HasTimer();
for (int i = 0; i < SortedTimers.Size() && !hasTimer; i++) for (int i = 0; i < SortedTimers.Size() && !hasTimer; i++)
if (const cTimer *Timer = SortedTimers[i]) if (const cTimer *Timer = SortedTimers[i])
@ -311,7 +328,17 @@ void cVeDcStatusInfo::Set(const cChannel *c) {
bool isDolby = c->Dpid(0); bool isDolby = c->Dpid(0);
bool isEncrypted = c->Ca(); bool isEncrypted = c->Ca();
bool isRecording = cRecordControls::Active(); bool isRecording = cRecordControls::Active();
cGlobalSortedTimers SortedTimers;// local and remote timers int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
for (int i = 0; i < SortedTimers.Size() && !isRecording; i++) for (int i = 0; i < SortedTimers.Size() && !isRecording; i++)
if (const cTimer *Timer = SortedTimers[i]) if (const cTimer *Timer = SortedTimers[i])
if (Timer->Recording()) if (Timer->Recording())

View File

@ -351,9 +351,19 @@ void cVeDmTimers::SetTokenContainer(void) {
bool cVeDmTimers::Parse(bool forced) { bool cVeDmTimers::Parse(bool forced) {
if (!cViewElement::Parse(forced)) if (!cViewElement::Parse(forced))
return false; return false;
tokenContainer->Clear(); tokenContainer->Clear();
cGlobalSortedTimers SortedTimers;// local and remote timers
int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
int numTimers = SortedTimers.Size(); int numTimers = SortedTimers.Size();
tokenContainer->AddIntToken((int)eDMTimersIT::numtimers, numTimers); tokenContainer->AddIntToken((int)eDMTimersIT::numtimers, numTimers);
tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, SortedTimers.NumTimerConfilicts()); tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, SortedTimers.NumTimerConfilicts());
@ -469,8 +479,15 @@ bool cVeDmCurrentschedule::Parse(bool forced) {
cDevice *device = cDevice::PrimaryDevice(); cDevice *device = cDevice::PrimaryDevice();
const cChannel *channel = NULL; const cChannel *channel = NULL;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
if (!device->Replaying() || device->Transferring()) { if (!device->Replaying() || device->Transferring()) {
channel = Channels.GetByNumber(device->CurrentChannel()); channel = channels->GetByNumber(device->CurrentChannel());
} }
if (channel) { if (channel) {
ParseFromChannel(channel); ParseFromChannel(channel);
@ -489,9 +506,17 @@ bool cVeDmCurrentschedule::Parse(bool forced) {
void cVeDmCurrentschedule::ParseFromChannel(const cChannel *channel) { void cVeDmCurrentschedule::ParseFromChannel(const cChannel *channel) {
const cEvent *event = NULL; const cEvent *event = NULL;
cSchedulesLock SchedulesLock;
if (const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock)) #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
if (const cSchedule *Schedule = Schedules->GetSchedule(channel)) LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock;
const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
#endif
if (schedules)
if (const cSchedule *Schedule = schedules->GetSchedule(channel))
event = Schedule->GetPresentEvent(); event = Schedule->GetPresentEvent();
if (!event) if (!event)
return; return;
@ -839,20 +864,37 @@ bool cVeDmLastrecordings::Parse(bool forced) {
return false; return false;
tokenContainer->Clear(); tokenContainer->Clear();
cGlobalSortedTimers SortedTimers;// local and remote timers int numTimers = 0;
int numTimers = SortedTimers.Size(); // BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
numTimers = Timers->Count();
#else
numTimers = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(numTimers); // local and remote timers
//set number of timers so that it is possible to adapt this viewelement accordingly //set number of timers so that it is possible to adapt this viewelement accordingly
tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, numTimers); tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, SortedTimers.Size());
list<cRecording*> orderedRecs; list<const cRecording*> orderedRecs;
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_RECORDINGS_READ;
const cRecordings* recordings = Recordings;
#else
const cRecordings* recordings = &Recordings;
#endif
for (const cRecording *recording = recordings->First(); recording; recording = recordings->Next(recording)) {
if (orderedRecs.size() == 0) { if (orderedRecs.size() == 0) {
orderedRecs.push_back(recording); orderedRecs.push_back(recording);
continue; continue;
} }
bool inserted = false; bool inserted = false;
for (list<cRecording*>::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { for (list<const cRecording*>::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) {
const cRecording *orderedRec = *it; const cRecording *orderedRec = *it;
if (recording->Start() >= orderedRec->Start()) { if (recording->Start() >= orderedRec->Start()) {
orderedRecs.insert(it, recording); orderedRecs.insert(it, recording);
@ -876,7 +918,7 @@ bool cVeDmLastrecordings::Parse(bool forced) {
tokenContainer->CreateLoopTokenContainer(&loopInfo); tokenContainer->CreateLoopTokenContainer(&loopInfo);
int i = 0; int i = 0;
for (list<cRecording*>::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { for (list<const cRecording*>::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) {
const cRecording *recording = *it; const cRecording *recording = *it;
#if APIVERSNUM >= 20101 #if APIVERSNUM >= 20101
if (recording->IsInUse()) { if (recording->IsInUse()) {
@ -1000,7 +1042,13 @@ bool cVeDmDetailheaderEpg::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::year, sStartTime->tm_year + 1900); tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::year, sStartTime->tm_year + 1900);
tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::daynumeric, sStartTime->tm_mday); tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::daynumeric, sStartTime->tm_mday);
tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::month, sStartTime->tm_mon+1); tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::month, sStartTime->tm_mon+1);
const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(event->ChannelID());
if (channel) { if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::channelname, channel->Name()); tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::channelname, channel->Name());
tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::channelnumber, channel->Number()); tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::channelnumber, channel->Number());
@ -1132,7 +1180,13 @@ bool cVeDmDetailheaderRec::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationeventhours, duration / 60); tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationeventhours, duration / 60);
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60));
} }
cChannel *channel = Channels.GetByChannelID(info->ChannelID()); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(info->ChannelID());
if (channel) { if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, channel->Name()); tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, *channel->GetChannelID().ToString()); tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, *channel->GetChannelID().ToString());

View File

@ -56,13 +56,20 @@ void cImageCache::CacheLogo(int width, int height) {
return; return;
if (width == 0 || height == 0) if (width == 0 || height == 0)
return; return;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
const cChannels* channels = &Channels;
#endif
int logosCached = 0; int logosCached = 0;
if (config.numLogosMax && config.numLogosMax < (int)channelLogoCache.size()) if (config.numLogosMax && config.numLogosMax < (int)channelLogoCache.size())
return; return;
for (const cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { for (const cChannel *channel = channels->First(); channel; channel = channels->Next(channel)) {
if (logosCached >= config.numLogosPerSizeInitial) if (logosCached >= config.numLogosPerSizeInitial)
break; break;
if (channel->GroupSep()) { if (channel->GroupSep()) {
@ -97,7 +104,13 @@ cImage *cImageCache::GetLogo(string channelID, int width, int height) {
return (cImage*)hit->second; return (cImage*)hit->second;
} else { } else {
tChannelID chanID = tChannelID::FromString(channelID.c_str()); tChannelID chanID = tChannelID::FromString(channelID.c_str());
const cChannel *channel = Channels.GetByChannelID(chanID); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(chanID);
if (!channel) if (!channel)
return NULL; return NULL;
bool success = LoadLogo(channel); bool success = LoadLogo(channel);
@ -151,7 +164,13 @@ cImage *cImageCache::GetSeparatorLogo(string name, int width, int height) {
bool cImageCache::LogoExists(string channelID) { bool cImageCache::LogoExists(string channelID) {
tChannelID chanID = tChannelID::FromString(channelID.c_str()); tChannelID chanID = tChannelID::FromString(channelID.c_str());
const cChannel *channel = Channels.GetByChannelID(chanID); #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
#else
cChannels* channels = &Channels;
#endif
const cChannel *channel = channels->GetByChannelID(chanID);
if (!channel) if (!channel)
return false; return false;
string logoLower = StrToLowerCase(channel->Name()); string logoLower = StrToLowerCase(channel->Name());

View File

@ -13,7 +13,7 @@ private:
int _count; int _count;
cString _latestFileName; cString _latestFileName;
void UpdateData(cRecording *Recording); void UpdateData(const cRecording *Recording);
cFolderInfoIntern *FindSubFolder(const char *Name) const; cFolderInfoIntern *FindSubFolder(const char *Name) const;
public: public:
@ -24,7 +24,7 @@ public:
// if "Add", missing folders are created // if "Add", missing folders are created
cFolderInfoIntern *Find(const char *Name, bool Add); cFolderInfoIntern *Find(const char *Name, bool Add);
void Add(cRecording *Recording); void Add(const cRecording *Recording);
cRecordingsFolderInfo::cFolderInfo *GetInfo(void) const; cRecordingsFolderInfo::cFolderInfo *GetInfo(void) const;
@ -44,9 +44,8 @@ cRecordingsFolderInfo::cFolderInfo::cFolderInfo(const char *Name, const char *Fu
} }
cRecordingsFolderInfo::cRecordingsFolderInfo(cRecordings &Recordings) cRecordingsFolderInfo::cRecordingsFolderInfo()
:_recordings(Recordings) : _root(NULL)
,_root(NULL)
{ {
Rebuild(); Rebuild();
} }
@ -59,44 +58,70 @@ cRecordingsFolderInfo::~cRecordingsFolderInfo(void)
void cRecordingsFolderInfo::Rebuild(void) void cRecordingsFolderInfo::Rebuild(void)
{ {
delete _root; cFolderInfoIntern *info;
_root = new cFolderInfoIntern(NULL, "");
delete _root;
_root = new cFolderInfoIntern(NULL, "");
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_RECORDINGS_READ;
const cRecordings* recordings = Recordings;
for (const cRecording *rec = recordings->First(); rec; rec = recordings->Next(rec))
{
info = _root->Find(rec->Folder(), true);
info->Add(rec);
}
#else
cString folder;
cThreadLock RecordingsLock(&Recordings);
// re-get state with lock held
Recordings.StateChanged(_recState);
for (cRecording *rec = Recordings.First(); rec; rec = Recordings.Next(rec))
{
# if APIVERSNUM < 20102
cThreadLock RecordingsLock(&_recordings);
// re-get state with lock held
_recordings.StateChanged(_recState);
cFolderInfoIntern *info;
cString folder;
for (cRecording *rec = _recordings.First(); rec; rec = _recordings.Next(rec)) {
#if APIVERSNUM < 20102
//cRecording::Folder() first available since VDR 2.1.2
const char *recName = rec->Name(); const char *recName = rec->Name();
if (const char *s = strrchr(recName, FOLDERDELIMCHAR)) { if (const char *s = strrchr(recName, FOLDERDELIMCHAR))
{
folder = recName; folder = recName;
folder.Truncate(s - recName); folder.Truncate(s - recName);
} }
else else
folder = ""; folder = "";
#else # else
folder = rec->Folder(); folder = rec->Folder();
#endif # endif
info = _root->Find(*folder, true); info = _root->Find(*folder, true);
info->Add(rec); info->Add(rec);
} }
#endif
} }
cRecordingsFolderInfo::cFolderInfo *cRecordingsFolderInfo::Get(const char *Folder) cRecordingsFolderInfo::cFolderInfo *cRecordingsFolderInfo::Get(const char *Folder)
{ {
cMutexLock lock(&_rootLock); cMutexLock lock(&_rootLock);
if (_recordings.StateChanged(_recState) || (_root == NULL)) #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
Rebuild(); static cStateKey recordingsKey;
const cRecordings* recordings = cRecordings::GetRecordingsRead(recordingsKey);
cFolderInfoIntern *info = _root->Find(Folder, false); int recStateChanged = recordings != 0;
if (info == NULL) if (recordings) recordingsKey.Remove();
return NULL; #else
int recStateChanged = Recordings.StateChanged(_recState);
return info->GetInfo(); #endif
if (recStateChanged || (_root == NULL))
Rebuild();
cFolderInfoIntern *info = _root->Find(Folder, false);
if (info == NULL)
return NULL;
return info->GetInfo();
} }
cString cRecordingsFolderInfo::DebugOutput(void) const cString cRecordingsFolderInfo::DebugOutput(void) const
@ -154,7 +179,7 @@ cRecordingsFolderInfo::cFolderInfoIntern *cRecordingsFolderInfo::cFolderInfoInte
return info; return info;
} }
void cRecordingsFolderInfo::cFolderInfoIntern::UpdateData(cRecording *Recording) void cRecordingsFolderInfo::cFolderInfoIntern::UpdateData(const cRecording *Recording)
{ {
// count every recording // count every recording
_count++; _count++;
@ -176,7 +201,7 @@ cRecordingsFolderInfo::cFolderInfoIntern *cRecordingsFolderInfo::cFolderInfoInte
return NULL; return NULL;
} }
void cRecordingsFolderInfo::cFolderInfoIntern::Add(cRecording *Recording) void cRecordingsFolderInfo::cFolderInfoIntern::Add(const cRecording *Recording)
{ {
if (Recording == NULL) if (Recording == NULL)
return; return;

View File

@ -9,7 +9,6 @@ public:
class cFolderInfoIntern; class cFolderInfoIntern;
private: private:
cRecordings &_recordings;
int _recState; int _recState;
cFolderInfoIntern *_root; cFolderInfoIntern *_root;
mutable cMutex _rootLock; mutable cMutex _rootLock;
@ -28,7 +27,7 @@ public:
cFolderInfo(const char *Name, const char *FullName, time_t Latest, int Count, const char *LatestFileName); cFolderInfo(const char *Name, const char *FullName, time_t Latest, int Count, const char *LatestFileName);
}; };
cRecordingsFolderInfo(cRecordings &Recordings); cRecordingsFolderInfo();
~cRecordingsFolderInfo(void); ~cRecordingsFolderInfo(void);
// caller must delete the cInfo object! // caller must delete the cInfo object!
@ -40,4 +39,4 @@ public:
cString DebugOutput(void) const; cString DebugOutput(void) const;
}; };
#endif // __RECFOLDERINFO_H #endif // __RECFOLDERINFO_H

View File

@ -6,7 +6,7 @@ static int CompareTimers(const void *a, const void *b) {
return (*(const cTimer **)a)->Compare(**(const cTimer **)b); return (*(const cTimer **)a)->Compare(**(const cTimer **)b);
} }
cGlobalSortedTimers::cGlobalSortedTimers(bool forceRefresh) : cVector<const cTimer *>(Timers.Count()) { cGlobalSortedTimers::cGlobalSortedTimers(int timerCount, bool forceRefresh) : cVector<const cTimer*>(timerCount) {
static bool initial = true; static bool initial = true;
static cRemoteTimerRefresh *remoteTimerRefresh = NULL; static cRemoteTimerRefresh *remoteTimerRefresh = NULL;
localTimer = NULL; localTimer = NULL;
@ -16,8 +16,16 @@ cGlobalSortedTimers::cGlobalSortedTimers(bool forceRefresh) : cVector<const cTim
//check if remotetimers plugin is available //check if remotetimers plugin is available
static cPlugin* pRemoteTimers = cPluginManager::GetPlugin("remotetimers"); static cPlugin* pRemoteTimers = cPluginManager::GetPlugin("remotetimers");
cSchedulesLock SchedulesLock; #if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); 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) { if (pRemoteTimers && initial) {
cString errorMsg; cString errorMsg;
@ -25,7 +33,7 @@ cGlobalSortedTimers::cGlobalSortedTimers(bool forceRefresh) : cVector<const cTim
initial = false; initial = false;
} }
for (cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) { for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer->HasFlags(tfActive)) if (Timer->HasFlags(tfActive))
Append(Timer); Append(Timer);
} }
@ -34,7 +42,7 @@ cGlobalSortedTimers::cGlobalSortedTimers(bool forceRefresh) : cVector<const cTim
if (pRemoteTimers) { if (pRemoteTimers) {
cTimer* remoteTimer = NULL; cTimer* remoteTimer = NULL;
while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) { while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) {
remoteTimer->SetEventFromSchedule(Schedules); // make sure the event is current remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current
if (remoteTimer->HasFlags(tfActive)) if (remoteTimer->HasFlags(tfActive))
Append(remoteTimer); Append(remoteTimer);
} }
@ -50,7 +58,7 @@ cGlobalSortedTimers::cGlobalSortedTimers(bool forceRefresh) : cVector<const cTim
localTimer[i] = true; localTimer[i] = true;
} else { } else {
localTimer[i] = false; localTimer[i] = false;
for (cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) { for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer == At(i)) { if (Timer == At(i)) {
localTimer[i] = true; localTimer[i] = true;
break; break;
@ -109,13 +117,18 @@ cRemoteTimerRefresh::~cRemoteTimerRefresh(void) {
} }
void cRemoteTimerRefresh::Action(void) { void cRemoteTimerRefresh::Action(void) {
#define REFESH_INTERVALL_MS 30000 #define REFESH_INTERVALL_MS 30000
while (Running()) { while (Running()) {
cCondWait::SleepMs(REFESH_INTERVALL_MS); cCondWait::SleepMs(REFESH_INTERVALL_MS);
if (!cOsd::IsOpen()) {//make sure that no timer is currently being edited // make sure that no timer is currently being edited
if (!cOsd::IsOpen()) {
cGlobalSortedTimers(true); cGlobalSortedTimers(true);
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_WRITE;
Timers->SetModified();
#else
Timers.SetModified(); Timers.SetModified();
#endif
} }
} }
} }

View File

@ -8,7 +8,7 @@ class cGlobalSortedTimers : public cVector<const cTimer *> {
private: private:
bool *localTimer; bool *localTimer;
public: public:
cGlobalSortedTimers(bool forceRefresh = false); cGlobalSortedTimers(int timerCount, bool forceRefresh = false);
virtual ~cGlobalSortedTimers(void); virtual ~cGlobalSortedTimers(void);
bool IsRemoteTimer(int i); bool IsRemoteTimer(int i);
int NumTimerConfilicts(void); int NumTimerConfilicts(void);