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 rather than a specific time. Well, let's see where this leads us...
- 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>.
* 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"
@ -43,6 +43,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
Schedules->Add(pSchedule);
}
bool Modified = false;
SI::EIT::Event SiEitEvent;
for (SI::Loop::Iterator it; eventLoop.hasNext(it); ) {
SiEitEvent = eventLoop.getNext(it);
@ -188,7 +190,10 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
if (LinkChannels)
channel->SetLinkChannels(LinkChannels);
Modified = true;
}
if (Modified)
pSchedule->Sort();
}
// --- cTDT ------------------------------------------------------------------

15
epg.c
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* 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"
@ -29,7 +29,6 @@ cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
description = NULL;
startTime = 0;
duration = 0;
channelNumber = 0;
}
cEvent::~cEvent()
@ -39,6 +38,12 @@ cEvent::~cEvent()
free(description);
}
bool cEvent::operator< (const cListObject &ListObject)
{
cEvent *e = (cEvent *)&ListObject;
return startTime < e->startTime;
}
void cEvent::SetEventID(u_int16_t EventID)
{
eventID = EventID;
@ -500,6 +505,11 @@ void cSchedule::ResetVersions(void)
p->SetVersion(0xFF);
}
void cSchedule::Sort(void)
{
events.Sort();
}
void cSchedule::Cleanup(void)
{
Cleanup(time(NULL));
@ -547,6 +557,7 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
if (p) {
if (!cEvent::Read(f, p))
return false;
p->Sort();
}
}
else {

8
epg.h
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* 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
@ -33,11 +33,10 @@ private:
char *description; // Description of this event
time_t startTime; // Start time of this event
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:
cEvent(tChannelID ChannelID, u_int16_t EventID);
~cEvent();
virtual bool operator< (const cListObject &ListObject);
tChannelID ChannelID(void) const { return channelID; }
u_int16_t EventID(void) const { return eventID; }
uchar TableID(void) const { return tableID; }
@ -48,7 +47,6 @@ public:
const char *Description(void) const { return description; }
time_t StartTime(void) const { return startTime; }
int Duration(void) const { return duration; }
int ChannelNumber(void) const { return channelNumber; }
const char *GetDateString(void) const;
const char *GetTimeString(void) const;
const char *GetEndTimeString(void) const;
@ -61,7 +59,6 @@ public:
void SetDescription(const char *Description);
void SetStartTime(time_t StartTime);
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;
static bool Read(FILE *f, cSchedule *Schedule);
void FixEpgBugs(void);
@ -78,6 +75,7 @@ public:
tChannelID ChannelID(void) const { return channelID; }
void SetRunningStatus(cEvent *Event, int RunningStatus);
void ResetVersions(void);
void Sort(void);
void Cleanup(time_t Time);
void Cleanup(void);
cEvent *AddEvent(cEvent *Event);

77
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@ -1195,15 +1195,16 @@ eOSState cMenuEvent::ProcessKey(eKeys Key)
class cMenuWhatsOnItem : public cOsdItem {
public:
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;
channel = Channel;
char *buffer = NULL;
cChannel *channel = Channels.GetByNumber(event->ChannelNumber());
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", event->ChannelNumber(), 6, channel ? channel->Name() : "???", 5, event->GetTimeString(), event->Title());
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", channel->Number(), 6, channel->Name(), 5, event->GetTimeString(), event->Title());
SetText(buffer, false);
}
@ -1226,39 +1227,18 @@ public:
int cMenuWhatsOn::currentChannel = 0;
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)
:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6)
{
const cSchedule *Schedule = Schedules->First();
const cEvent **pArray = NULL;
int num = 0;
while (Schedule) {
pArray = (const cEvent **)realloc(pArray, (num + 1) * sizeof(cEvent *));
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);
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
if (Schedule) {
const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
if (Event)
Add(new cMenuWhatsOnItem(Event, Channel), Channel->Number() == CurrentChannelNr);
}
}
currentChannel = CurrentChannelNr;
free(pArray);
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());
if (mi) {
scheduleEvent = mi->event;
currentChannel = mi->event->ChannelNumber();
currentChannel = mi->channel->Number();
}
}
break;
@ -1376,11 +1356,6 @@ cMenuSchedule::~cMenuSchedule()
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)
{
Clear();
@ -1392,22 +1367,12 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
if (Schedule) {
int num = Schedule->NumEvents();
const cEvent **pArray = MALLOC(const cEvent *, num);
if (pArray) {
time_t now = time(NULL);
int numreal = 0;
for (int a = 0; a < num; a++) {
const cEvent *Event = Schedule->GetEventNumber(a);
if (Event->StartTime() + Event->Duration() > now)
pArray[numreal++] = Event;
}
qsort(pArray, numreal, sizeof(cEvent *), CompareEventTime);
for (int a = 0; a < numreal; a++)
Add(new cMenuScheduleItem(pArray[a]));
free(pArray);
}
time_t now = time(NULL);
for (int a = 0; a < num; a++) {
const cEvent *Event = Schedule->GetEventNumber(a);
if (Event->StartTime() + Event->Duration() > now)
Add(new cMenuScheduleItem(Event));
}
}
}
}