mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-08 00:43:54 +00:00
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { dayInMs, getFirstEvent } from 'ontime-utils';
|
|
import { OntimeEvent, MaybeNumber, PlayableEvent, isPlayableEvent } from 'ontime-types';
|
|
|
|
import { normaliseEndTime } from './timerUtils.js';
|
|
|
|
/**
|
|
* Finds current event in a rolling rundown
|
|
*/
|
|
export function loadRoll(
|
|
timedEvents: OntimeEvent[],
|
|
timeNow: number,
|
|
): {
|
|
event: PlayableEvent | null;
|
|
index: MaybeNumber;
|
|
isPending?: boolean;
|
|
} {
|
|
const { firstEvent } = getFirstEvent(timedEvents);
|
|
|
|
if (!firstEvent) {
|
|
return { event: null, index: null };
|
|
}
|
|
|
|
// we know we are in the middle of the rundown and we need to find the current event
|
|
// account for number of times we went over midnight
|
|
let daySpan = 0;
|
|
|
|
for (let i = 0; i < timedEvents.length; i++) {
|
|
const event = timedEvents[i];
|
|
|
|
if (!isPlayableEvent(event)) {
|
|
continue;
|
|
}
|
|
|
|
if (event.duration === 0) {
|
|
continue;
|
|
}
|
|
|
|
// we check if event crosses midnight
|
|
if (event.timeStart > event.timeEnd) {
|
|
daySpan++;
|
|
}
|
|
|
|
const correctedDays = dayInMs * daySpan;
|
|
const correctedStart = event.timeStart + correctedDays;
|
|
const correctedEnd = event.timeEnd + correctedDays;
|
|
|
|
/**
|
|
* there are 3 possible states for an event
|
|
* 1. event is already finished
|
|
* 2. event is running
|
|
* 3. event is in the future
|
|
*/
|
|
|
|
// 1. event is already finished
|
|
// when does the event end (handle midnight)
|
|
const normalEnd = normaliseEndTime(correctedStart, correctedEnd);
|
|
if (normalEnd <= timeNow) {
|
|
continue;
|
|
}
|
|
|
|
// 2. event is running and is the first event in our time slot
|
|
const isFromDayBefore = normalEnd > dayInMs && timeNow < event.timeEnd;
|
|
const hasStarted = isFromDayBefore || timeNow >= event.timeStart;
|
|
if (hasStarted) {
|
|
return { event, index: i };
|
|
}
|
|
|
|
// 3. event will run in the future
|
|
// we set the isPending flag to indicate that the event is currently playing
|
|
return { event, index: i, isPending: true };
|
|
}
|
|
|
|
// in case we were unable to find anything, we load the first event
|
|
return { event: firstEvent, index: 0, isPending: true };
|
|
}
|
|
|
|
/**
|
|
* Utility function, checks whether the event start is the day after
|
|
*/
|
|
export function normaliseRollStart(start: number, clock: number) {
|
|
return start < clock ? start + dayInMs : start;
|
|
}
|