mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	The EPG data is now always kept sorted chronologically in the internal data structures
This commit is contained in:
		
							
								
								
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								eit.c
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								epg.c
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								epg.h
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								menu.c
									
									
									
									
									
								
							| @@ -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)); | ||||
|             } | ||||
|         } | ||||
|      } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user