From 94e80606c5ba382c04a146dd4a998ae7093f3adb Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sun, 21 Sep 2014 23:42:51 +0100 Subject: [PATCH] Implement "holdover events," noting those log events which are not listed in the currently loaded log but which are present because they were playing when this log was loaded. This fixes problems arising when the duplicate IDs thus introduced cause confusion. --- lib/rdlog_event.cpp | 18 ++++++++++-------- lib/rdlog_event.h | 4 ++-- lib/rdlog_line.cpp | 11 +++++++++++ lib/rdlog_line.h | 3 +++ rdairplay/log_play.cpp | 40 ++++++++++++++++++++++++++++++++-------- 5 files changed, 58 insertions(+), 18 deletions(-) diff --git a/lib/rdlog_event.cpp b/lib/rdlog_event.cpp index d02b6cd0..6b368afd 100644 --- a/lib/rdlog_event.cpp +++ b/lib/rdlog_event.cpp @@ -626,20 +626,22 @@ void RDLogEvent::setLogLine(int line,RDLogLine *ll) } -RDLogLine *RDLogEvent::loglineById(int id) const +RDLogLine *RDLogEvent::loglineById(int id, bool ignore_holdovers) const { - for(int i=0;iid()==id) { - return log_line[i]; - } - } - return NULL; + int line = lineById(id, ignore_holdovers); + if(line == -1) + return NULL; + else + return log_line[line]; } -int RDLogEvent::lineById(int id) const +int RDLogEvent::lineById(int id, bool ignore_holdovers) const { for(int i=0;iisHoldover()) { + continue; + } if(log_line[i]->id()==id) { return i; } diff --git a/lib/rdlog_event.h b/lib/rdlog_event.h index c44ac061..46ae3f52 100644 --- a/lib/rdlog_event.h +++ b/lib/rdlog_event.h @@ -61,8 +61,8 @@ class RDLogEvent QTime blockStartTime(int line); RDLogLine *logLine(int line) const; void setLogLine(int line,RDLogLine *ll); - RDLogLine *loglineById(int id) const; - int lineById(int id) const; + RDLogLine *loglineById(int id, bool ignore_holdovers=false) const; + int lineById(int id, bool ignore_holdovers=false) const; int lineByStartHour(int hour,RDLogLine::StartTimeType type) const; int lineByStartHour(int hour) const; int nextTimeStart(QTime after); diff --git a/lib/rdlog_line.cpp b/lib/rdlog_line.cpp index 4972d136..e0de1876 100644 --- a/lib/rdlog_line.cpp +++ b/lib/rdlog_line.cpp @@ -174,6 +174,7 @@ void RDLogLine::clear() log_link_id=-1; log_link_embedded=false; log_start_source=RDLogLine::StartUnknown; + is_holdover = false; } @@ -2093,3 +2094,13 @@ QString RDLogLine::sourceText(RDLogLine::Source src) } return QObject::tr("Unknown"); } + +bool RDLogLine::isHoldover() const +{ + return is_holdover; +} + +void RDLogLine::setHoldover(bool b) +{ + is_holdover = b; +} diff --git a/lib/rdlog_line.h b/lib/rdlog_line.h index 037fccfe..4855fc8f 100644 --- a/lib/rdlog_line.h +++ b/lib/rdlog_line.h @@ -265,6 +265,8 @@ class RDLogLine static QString typeText(RDLogLine::Type type); static QString timeTypeText(RDLogLine::TimeType type); static QString sourceText(RDLogLine::Source src); + bool isHoldover() const; + void setHoldover(bool); private: int log_id; @@ -368,6 +370,7 @@ class RDLogLine int log_link_end_slop; int log_link_id; bool log_link_embedded; + bool is_holdover; }; diff --git a/rdairplay/log_play.cpp b/rdairplay/log_play.cpp index eeb25369..68e20fdc 100644 --- a/rdairplay/log_play.cpp +++ b/rdairplay/log_play.cpp @@ -503,7 +503,7 @@ void LogPlay::load() if(lines[running-1]<(size()-1)) { remove(lines[running-1]+1,size()-lines[running-1]-1,false); } - for(int i=running-2;i>0;i--) { + for(int i=running-1;i>0;i--) { remove(lines[i-1]+1,lines[i]-lines[i-1]-1,false); } if(lines[0]!=0) { @@ -511,6 +511,12 @@ void LogPlay::load() } } + // Note that events left in the log are holdovers from a previous log. + // Their IDs may clash with those of events in the log we will now load, + // and it may be appropriate to ignore them in that case. + for(int i = 0, ilim = size(); i != ilim; ++i) + logLine(i)->setHoldover(true); + // // Load Events // @@ -588,6 +594,7 @@ bool LogPlay::refresh() int current_id=-1; int lines[TRANSPORT_QUANTITY]; int running; + int first_non_holdover = 0; if(play_macro_running) { play_refresh_pending=true; @@ -633,7 +640,12 @@ bool LogPlay::refresh() for(int i=0;istatus()!=RDLogLine::Scheduled) { - if((s=e->loglineById(d->id()))!=NULL) { + if((!d->isHoldover()) && (s=e->loglineById(d->id()))!=NULL) { + // A holdover event may be finished or active, + // but should not supress the addition of an + // event with the same ID in this log. + // Incrementing its ID here may flag it as an orphan + // to be removed in step 4. s->incrementPass(); } d->incrementPass(); @@ -649,6 +661,15 @@ bool LogPlay::refresh() } } + // Find first non-holdover event, where start-of-log + // new events should be added: + for(int i=0;isize();i++) { + if(logLine(i)->isHoldover()) + ++first_non_holdover; + else + break; + } + // // Pass 3: Add New Events // @@ -656,15 +677,15 @@ bool LogPlay::refresh() s=e->logLine(i); if(s->pass()==0) { if((prev_line=(i-1))<0) { // First Event - insert(0,s,false,true); + insert(first_non_holdover,s,false,true); } else { prev_id=e->logLine(prev_line)->id(); - insert(lineById(prev_id)+1,s,false,true); + insert(lineById(prev_id, /*ignore_holdovers=*/true)+1,s,false,true); } } else { - loglineById(s->id())->incrementPass(); + loglineById(s->id(), /*ignore_holdovers=*/true)->incrementPass(); } } @@ -681,13 +702,16 @@ bool LogPlay::refresh() // // Restore Next Event // - if(current_id!=-1 && e->loglineById(current_id)!=NULL) { //Make Next after currently playing cart - if((next_line=lineById(current_id))>=0) { + if(current_id!=-1 && e->loglineById(current_id)!=NULL) { + // Make Next after currently playing cart + // The next event cannot have been a holdover, + // as holdovers are always either active or finished. + if((next_line=lineById(current_id, /*ignore_holdovers=*/true))>=0) { makeNext(next_line+1,false); } } else { - if((next_line=lineById(next_id))>=0) { + if((next_line=lineById(next_id, /*ignore_holdovers=*/true))>=0) { makeNext(next_line,false); } }