1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

The EPG data is now always kept sorted chronologically in the internal data structures

This commit is contained in:
Klaus Schmidinger 2004-02-21 13:56:20 +01:00
parent 15e6b261ba
commit 340d9bcb0f
5 changed files with 46 additions and 64 deletions

View File

@ -2681,3 +2681,6 @@ Video Disk Recorder Revision History
event randomly, making it impossible for a timer to be programmed on a ceartain event randomly, making it impossible for a timer to be programmed on a ceartain
event rather than a specific time. Well, let's see where this leads us... event rather than a specific time. Well, let's see where this leads us...
- Removed the obsolete 'present' and 'following' handling from the EPG data. - Removed the obsolete 'present' and 'following' handling from the EPG data.
- The EPG data is now always kept sorted chronologically in the internal data
structures. This also means that any EPG data retrieved through the SVRDP
command LSTE is guaranteed to be sorted by start time.

7
eit.c
View File

@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
* *
* $Id: eit.c 1.87 2004/02/21 12:20:26 kls Exp $ * $Id: eit.c 1.88 2004/02/21 13:26:52 kls Exp $
*/ */
#include "eit.h" #include "eit.h"
@ -43,6 +43,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
Schedules->Add(pSchedule); Schedules->Add(pSchedule);
} }
bool Modified = false;
SI::EIT::Event SiEitEvent; SI::EIT::Event SiEitEvent;
for (SI::Loop::Iterator it; eventLoop.hasNext(it); ) { for (SI::Loop::Iterator it; eventLoop.hasNext(it); ) {
SiEitEvent = eventLoop.getNext(it); SiEitEvent = eventLoop.getNext(it);
@ -188,7 +190,10 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
if (LinkChannels) if (LinkChannels)
channel->SetLinkChannels(LinkChannels); channel->SetLinkChannels(LinkChannels);
Modified = true;
} }
if (Modified)
pSchedule->Sort();
} }
// --- cTDT ------------------------------------------------------------------ // --- cTDT ------------------------------------------------------------------

15
epg.c
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by * Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* *
* $Id: epg.c 1.7 2004/02/21 12:32:31 kls Exp $ * $Id: epg.c 1.8 2004/02/21 13:46:23 kls Exp $
*/ */
#include "epg.h" #include "epg.h"
@ -29,7 +29,6 @@ cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
description = NULL; description = NULL;
startTime = 0; startTime = 0;
duration = 0; duration = 0;
channelNumber = 0;
} }
cEvent::~cEvent() cEvent::~cEvent()
@ -39,6 +38,12 @@ cEvent::~cEvent()
free(description); free(description);
} }
bool cEvent::operator< (const cListObject &ListObject)
{
cEvent *e = (cEvent *)&ListObject;
return startTime < e->startTime;
}
void cEvent::SetEventID(u_int16_t EventID) void cEvent::SetEventID(u_int16_t EventID)
{ {
eventID = EventID; eventID = EventID;
@ -500,6 +505,11 @@ void cSchedule::ResetVersions(void)
p->SetVersion(0xFF); p->SetVersion(0xFF);
} }
void cSchedule::Sort(void)
{
events.Sort();
}
void cSchedule::Cleanup(void) void cSchedule::Cleanup(void)
{ {
Cleanup(time(NULL)); Cleanup(time(NULL));
@ -547,6 +557,7 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
if (p) { if (p) {
if (!cEvent::Read(f, p)) if (!cEvent::Read(f, p))
return false; return false;
p->Sort();
} }
} }
else { else {

8
epg.h
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by * Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* *
* $Id: epg.h 1.6 2004/02/21 12:31:43 kls Exp $ * $Id: epg.h 1.7 2004/02/21 13:46:18 kls Exp $
*/ */
#ifndef __EPG_H #ifndef __EPG_H
@ -33,11 +33,10 @@ private:
char *description; // Description of this event char *description; // Description of this event
time_t startTime; // Start time of this event time_t startTime; // Start time of this event
int duration; // Duration of this event in seconds int duration; // Duration of this event in seconds
//XXX find an other solution, avoiding channelNumber???
int channelNumber; // the actual channel number from VDR's channel list (used in cMenuSchedule for sorting by channel number)
public: public:
cEvent(tChannelID ChannelID, u_int16_t EventID); cEvent(tChannelID ChannelID, u_int16_t EventID);
~cEvent(); ~cEvent();
virtual bool operator< (const cListObject &ListObject);
tChannelID ChannelID(void) const { return channelID; } tChannelID ChannelID(void) const { return channelID; }
u_int16_t EventID(void) const { return eventID; } u_int16_t EventID(void) const { return eventID; }
uchar TableID(void) const { return tableID; } uchar TableID(void) const { return tableID; }
@ -48,7 +47,6 @@ public:
const char *Description(void) const { return description; } const char *Description(void) const { return description; }
time_t StartTime(void) const { return startTime; } time_t StartTime(void) const { return startTime; }
int Duration(void) const { return duration; } int Duration(void) const { return duration; }
int ChannelNumber(void) const { return channelNumber; }
const char *GetDateString(void) const; const char *GetDateString(void) const;
const char *GetTimeString(void) const; const char *GetTimeString(void) const;
const char *GetEndTimeString(void) const; const char *GetEndTimeString(void) const;
@ -61,7 +59,6 @@ public:
void SetDescription(const char *Description); void SetDescription(const char *Description);
void SetStartTime(time_t StartTime); void SetStartTime(time_t StartTime);
void SetDuration(int Duration); void SetDuration(int Duration);
void SetChannelNumber(int ChannelNumber) const { ((cEvent *)this)->channelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const' //XXX
void Dump(FILE *f, const char *Prefix = "") const; void Dump(FILE *f, const char *Prefix = "") const;
static bool Read(FILE *f, cSchedule *Schedule); static bool Read(FILE *f, cSchedule *Schedule);
void FixEpgBugs(void); void FixEpgBugs(void);
@ -78,6 +75,7 @@ public:
tChannelID ChannelID(void) const { return channelID; } tChannelID ChannelID(void) const { return channelID; }
void SetRunningStatus(cEvent *Event, int RunningStatus); void SetRunningStatus(cEvent *Event, int RunningStatus);
void ResetVersions(void); void ResetVersions(void);
void Sort(void);
void Cleanup(time_t Time); void Cleanup(time_t Time);
void Cleanup(void); void Cleanup(void);
cEvent *AddEvent(cEvent *Event); cEvent *AddEvent(cEvent *Event);

63
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 1.286 2004/02/15 14:29:53 kls Exp $ * $Id: menu.c 1.287 2004/02/21 13:53:25 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -1195,15 +1195,16 @@ eOSState cMenuEvent::ProcessKey(eKeys Key)
class cMenuWhatsOnItem : public cOsdItem { class cMenuWhatsOnItem : public cOsdItem {
public: public:
const cEvent *event; const cEvent *event;
cMenuWhatsOnItem(const cEvent *Event); const cChannel *channel;
cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel);
}; };
cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event) cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel)
{ {
event = Event; event = Event;
channel = Channel;
char *buffer = NULL; char *buffer = NULL;
cChannel *channel = Channels.GetByNumber(event->ChannelNumber()); asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", channel->Number(), 6, channel->Name(), 5, event->GetTimeString(), event->Title());
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", event->ChannelNumber(), 6, channel ? channel->Name() : "???", 5, event->GetTimeString(), event->Title());
SetText(buffer, false); SetText(buffer, false);
} }
@ -1226,39 +1227,18 @@ public:
int cMenuWhatsOn::currentChannel = 0; int cMenuWhatsOn::currentChannel = 0;
const cEvent *cMenuWhatsOn::scheduleEvent = NULL; const cEvent *cMenuWhatsOn::scheduleEvent = NULL;
static int CompareEventChannel(const void *p1, const void *p2)
{
return (int)( (*(const cEvent **)p1)->ChannelNumber() - (*(const cEvent **)p2)->ChannelNumber());
}
cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr)
:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6) :cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6)
{ {
const cSchedule *Schedule = Schedules->First(); for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
const cEvent **pArray = NULL; const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
int num = 0; if (Schedule) {
const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
while (Schedule) { if (Event)
pArray = (const cEvent **)realloc(pArray, (num + 1) * sizeof(cEvent *)); Add(new cMenuWhatsOnItem(Event, Channel), Channel->Number() == CurrentChannelNr);
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
if (pArray[num]) {
cChannel *channel = Channels.GetByChannelID(pArray[num]->ChannelID(), true);
if (channel) {
pArray[num]->SetChannelNumber(channel->Number());
num++;
} }
} }
Schedule = (const cSchedule *)Schedules->Next(Schedule);
}
qsort(pArray, num, sizeof(cEvent *), CompareEventChannel);
for (int a = 0; a < num; a++)
Add(new cMenuWhatsOnItem(pArray[a]), pArray[a]->ChannelNumber() == CurrentChannelNr);
currentChannel = CurrentChannelNr; currentChannel = CurrentChannelNr;
free(pArray);
SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch")); SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch"));
} }
@ -1310,7 +1290,7 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current()); cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current());
if (mi) { if (mi) {
scheduleEvent = mi->event; scheduleEvent = mi->event;
currentChannel = mi->event->ChannelNumber(); currentChannel = mi->channel->Number();
} }
} }
break; break;
@ -1376,11 +1356,6 @@ cMenuSchedule::~cMenuSchedule()
cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared
} }
static int CompareEventTime(const void *p1, const void *p2)
{
return (int)((*(cEvent **)p1)->StartTime() - (*(cEvent **)p2)->StartTime());
}
void cMenuSchedule::PrepareSchedule(cChannel *Channel) void cMenuSchedule::PrepareSchedule(cChannel *Channel)
{ {
Clear(); Clear();
@ -1392,21 +1367,11 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
if (Schedule) { if (Schedule) {
int num = Schedule->NumEvents(); int num = Schedule->NumEvents();
const cEvent **pArray = MALLOC(const cEvent *, num);
if (pArray) {
time_t now = time(NULL); time_t now = time(NULL);
int numreal = 0;
for (int a = 0; a < num; a++) { for (int a = 0; a < num; a++) {
const cEvent *Event = Schedule->GetEventNumber(a); const cEvent *Event = Schedule->GetEventNumber(a);
if (Event->StartTime() + Event->Duration() > now) if (Event->StartTime() + Event->Duration() > now)
pArray[numreal++] = Event; Add(new cMenuScheduleItem(Event));
}
qsort(pArray, numreal, sizeof(cEvent *), CompareEventTime);
for (int a = 0; a < numreal; a++)
Add(new cMenuScheduleItem(pArray[a]));
free(pArray);
} }
} }
} }