mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-18 13:44:12 +00:00
fix: count-to-end events break link chain
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import type { MaybeNumber, OntimeEvent } from 'ontime-types';
|
||||
import { OffsetMode } from 'ontime-types';
|
||||
|
||||
import { dayInMs } from './conversionUtils.js';
|
||||
|
||||
/**
|
||||
* @param event the event that we are counting to
|
||||
* @param currentDay the day offset of the currently running event
|
||||
* @param totalGap accumulated gap from the current event
|
||||
* @param isLinkedToLoaded is this event part of a chain linking back to the current loaded event
|
||||
* @param offset
|
||||
* @returns
|
||||
*/
|
||||
export function getExpectedStart(
|
||||
event: Pick<OntimeEvent, 'timeStart' | 'dayOffset' | 'delay'>,
|
||||
state: {
|
||||
currentDay: number; // the current day from the rundown
|
||||
totalGap: number;
|
||||
isLinkedToLoaded: boolean;
|
||||
offset: number;
|
||||
mode: OffsetMode;
|
||||
actualStart: MaybeNumber;
|
||||
plannedStart: MaybeNumber;
|
||||
},
|
||||
): number {
|
||||
const { timeStart, dayOffset, delay } = event;
|
||||
const { currentDay, totalGap, isLinkedToLoaded, offset, mode, actualStart, plannedStart } = state;
|
||||
|
||||
//How many days from the currently running event to this one
|
||||
const relativeDayOffset = dayOffset - currentDay;
|
||||
|
||||
const delayedStart = Math.max(0, timeStart + delay);
|
||||
|
||||
//The normalised start time of this event relative to the currently running event
|
||||
const normalisedTimeStart = delayedStart + relativeDayOffset * dayInMs;
|
||||
|
||||
let relativeStartOffset = 0;
|
||||
|
||||
if (mode === OffsetMode.Relative) {
|
||||
relativeStartOffset = (actualStart ?? 0) + currentDay * dayInMs - (plannedStart ?? 0);
|
||||
}
|
||||
|
||||
const scheduledStartTime = normalisedTimeStart + relativeStartOffset;
|
||||
|
||||
const offsetStartTime = scheduledStartTime + offset;
|
||||
|
||||
if (isLinkedToLoaded) {
|
||||
//if we are directly linked back to the loaded event we just follow the offset
|
||||
return offsetStartTime;
|
||||
}
|
||||
|
||||
const gapsCanCompensateForOffset = totalGap > offset;
|
||||
if (gapsCanCompensateForOffset) {
|
||||
// if we are ahead of schedule or the gap can compensate for the amount we are behind then expect to start at the scheduled time
|
||||
return scheduledStartTime;
|
||||
}
|
||||
|
||||
// otherwise consume as much of the offset as possible with the gap
|
||||
const offsetStartTimeBufferedByGaps = offsetStartTime - totalGap;
|
||||
return offsetStartTimeBufferedByGaps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param event the event that we are counting to
|
||||
* @param currentDay the day offset of the currently running event
|
||||
* @param totalGap accumulated gap from the current event
|
||||
* @param isLinkedToLoaded is this event part of a chain linking back to the current loaded event
|
||||
* @param offset
|
||||
* @returns
|
||||
*/
|
||||
export function getExpectedEnd(
|
||||
event: Pick<OntimeEvent, 'timeStart' | 'dayOffset' | 'delay' | 'duration' | 'countToEnd'>,
|
||||
state: {
|
||||
currentDay: number; // the current day from the rundown
|
||||
totalGap: number;
|
||||
isLinkedToLoaded: boolean;
|
||||
offset: number;
|
||||
mode: OffsetMode;
|
||||
actualStart: MaybeNumber;
|
||||
plannedStart: MaybeNumber;
|
||||
},
|
||||
): number {
|
||||
// expected start encodes the offset from current delays
|
||||
const expectedStart = getExpectedStart(event, state);
|
||||
|
||||
// count to end events should finish on schedule unlesss the start is compromised
|
||||
if (event.countToEnd) {
|
||||
// count to end take scheduled delays into consideration
|
||||
const plannedEnd = event.timeStart + event.duration + event.delay;
|
||||
return Math.max(expectedStart, plannedEnd);
|
||||
}
|
||||
|
||||
return expectedStart + event.duration;
|
||||
}
|
||||
Reference in New Issue
Block a user