mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-15 04:13:47 +00:00
refactor(timer): elapsed is active time from start
This commit is contained in:
committed by
Carlos Valente
parent
4f4626a163
commit
161ab3fe13
@@ -5,6 +5,7 @@ import type { RuntimeState } from '../../stores/runtimeState.js';
|
||||
import {
|
||||
findDayOffset,
|
||||
getCurrent,
|
||||
getElapsed,
|
||||
getExpectedFinish,
|
||||
getRuntimeOffset,
|
||||
getTimerPhase,
|
||||
@@ -15,6 +16,56 @@ import {
|
||||
|
||||
const asTimeOfDay = (value: number): RuntimeState['clock'] => value as RuntimeState['clock'];
|
||||
|
||||
describe('getElapsed()', () => {
|
||||
it('returns active elapsed time from startedAt without add-time adjustments', () => {
|
||||
const state = {
|
||||
clock: 5 * MILLIS_PER_MINUTE,
|
||||
timer: {
|
||||
addedTime: -10 * MILLIS_PER_MINUTE,
|
||||
current: 15 * MILLIS_PER_MINUTE,
|
||||
duration: 20 * MILLIS_PER_MINUTE,
|
||||
startedAt: 2 * MILLIS_PER_MINUTE,
|
||||
},
|
||||
_timer: {
|
||||
pausedAt: null,
|
||||
pausedDuration: 0,
|
||||
},
|
||||
} as RuntimeState;
|
||||
|
||||
expect(getElapsed(state)).toBe(3 * MILLIS_PER_MINUTE);
|
||||
});
|
||||
|
||||
it('subtracts accumulated pause time', () => {
|
||||
const state = {
|
||||
clock: 10 * MILLIS_PER_MINUTE,
|
||||
timer: {
|
||||
startedAt: 2 * MILLIS_PER_MINUTE,
|
||||
},
|
||||
_timer: {
|
||||
pausedAt: null,
|
||||
pausedDuration: 5 * MILLIS_PER_MINUTE,
|
||||
},
|
||||
} as RuntimeState;
|
||||
|
||||
expect(getElapsed(state)).toBe(3 * MILLIS_PER_MINUTE);
|
||||
});
|
||||
|
||||
it('uses the current pause start while paused', () => {
|
||||
const state = {
|
||||
clock: 10 * MILLIS_PER_MINUTE,
|
||||
timer: {
|
||||
startedAt: 2 * MILLIS_PER_MINUTE,
|
||||
},
|
||||
_timer: {
|
||||
pausedAt: 7 * MILLIS_PER_MINUTE,
|
||||
pausedDuration: 1 * MILLIS_PER_MINUTE,
|
||||
},
|
||||
} as RuntimeState;
|
||||
|
||||
expect(getElapsed(state)).toBe(4 * MILLIS_PER_MINUTE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getExpectedFinish()', () => {
|
||||
it('is null if we havent started', () => {
|
||||
const state = {
|
||||
|
||||
@@ -47,6 +47,23 @@ describe('isRestorePoint()', () => {
|
||||
expect(isRestorePoint(restorePoint)).toBe(true);
|
||||
});
|
||||
|
||||
it('accepts optional paused duration', () => {
|
||||
const restorePoint: RestorePoint = {
|
||||
playback: Playback.Roll,
|
||||
selectedEventId: '123',
|
||||
startedAt: 1,
|
||||
addedTime: 2,
|
||||
pausedAt: null,
|
||||
pausedDuration: 3000,
|
||||
firstStart: 1,
|
||||
startEpoch: asInstant(1),
|
||||
currentDay: 0,
|
||||
};
|
||||
|
||||
expect(isRestorePoint(restorePoint)).toBe(true);
|
||||
expect(isRestorePoint({ ...restorePoint, pausedDuration: '3000' })).toBe(false);
|
||||
});
|
||||
|
||||
describe('rejects a badly formatted file', () => {
|
||||
it('with invalid playback value', () => {
|
||||
const restorePoint = {
|
||||
|
||||
@@ -46,6 +46,10 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('pausedDuration' in restorePoint && !is.number(restorePoint.pausedDuration)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is.number(restorePoint.firstStart) && restorePoint.firstStart !== null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export type RestorePoint = {
|
||||
startedAt: MaybeNumber;
|
||||
addedTime: number;
|
||||
pausedAt: MaybeNumber;
|
||||
pausedDuration?: number;
|
||||
firstStart: MaybeNumber;
|
||||
startEpoch: Maybe<Instant>;
|
||||
currentDay: MaybeNumber;
|
||||
|
||||
@@ -760,6 +760,7 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
|
||||
startedAt: state.timer.startedAt,
|
||||
addedTime: state.timer.addedTime,
|
||||
pausedAt: state._timer.pausedAt,
|
||||
pausedDuration: state._timer.pausedDuration,
|
||||
firstStart: state.rundown.actualStart,
|
||||
startEpoch: state._startEpoch,
|
||||
currentDay: state.rundown.currentDay,
|
||||
|
||||
@@ -33,7 +33,8 @@ export function getShouldClockUpdate(previousUpdate: number, now: number): boole
|
||||
* Checks whether we should update the timer values
|
||||
* - `current` and `secondaryTimer` trigger on seconds roll over
|
||||
* - the rest trigger on any change
|
||||
* - `elapsed` and `expectedFinish` is not checked
|
||||
* - `elapsed` changes alongside `current`
|
||||
* - `expectedFinish` is not checked
|
||||
*/
|
||||
export function getShouldTimerUpdate(previousValue: TimerState | undefined, currentValue: TimerState): boolean {
|
||||
if (previousValue === undefined) return true;
|
||||
@@ -48,7 +49,7 @@ export function getShouldTimerUpdate(previousValue: TimerState | undefined, curr
|
||||
previousValue.phase !== currentValue.phase ||
|
||||
previousValue.playback !== currentValue.playback ||
|
||||
previousValue.startedAt !== currentValue.startedAt
|
||||
// elapsed - this would be the direct invert of current value so no need to check
|
||||
// elapsed - this is derived from current / duration / addedTime, so the fields above cover it
|
||||
// expectedFinish - this will be moved out by the current value going into over time, no need to check
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,33 @@ export function getCurrent(state: RuntimeState): number {
|
||||
return startedAt + duration + addedTime - clock - correctDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates active time elapsed since the timer started.
|
||||
*/
|
||||
export function getElapsed(state: RuntimeState): MaybeNumber {
|
||||
const { clock } = state;
|
||||
const { startedAt } = state.timer;
|
||||
const { pausedAt, pausedDuration } = state._timer;
|
||||
|
||||
if (startedAt === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const referenceClock = pausedAt ?? clock;
|
||||
const elapsedSinceStart = getTimeSinceStart(referenceClock, startedAt);
|
||||
const activeElapsed = elapsedSinceStart - pausedDuration;
|
||||
|
||||
return Math.max(0, activeElapsed);
|
||||
}
|
||||
|
||||
function getTimeSinceStart(clock: TimeOfDay, startedAt: number): number {
|
||||
if (clock < startedAt) {
|
||||
return clock + dayInMs - startedAt;
|
||||
}
|
||||
|
||||
return clock - startedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether we have skipped out of the event
|
||||
* @param {RuntimeState} state runtime state
|
||||
|
||||
Reference in New Issue
Block a user