refactor: declare timer phase

This commit is contained in:
Carlos Valente
2024-06-02 22:10:23 +02:00
committed by Carlos Valente
parent a53d354b16
commit fd2eee32aa
6 changed files with 159 additions and 5 deletions
@@ -1,11 +1,12 @@
import { MILLIS_PER_HOUR, dayInMs, millisToString } from 'ontime-utils';
import { EndAction, OntimeEvent, Playback, TimeStrategy, TimerType } from 'ontime-types';
import { EndAction, OntimeEvent, Playback, TimeStrategy, TimerPhase, TimerType } from 'ontime-types';
import {
getCurrent,
getExpectedFinish,
getRollTimers,
getRuntimeOffset,
getTimerPhase,
getTotalDuration,
normaliseEndTime,
skippedOutOfEvent,
@@ -1756,3 +1757,97 @@ describe('getTotalDuration()', () => {
expect(millisToString(duration)).toBe('62:00:00');
});
});
describe('getTimerPhase()', () => {
it('should be None if the timer is not running', () => {
const state = {
timer: {
addedTime: 0,
current: null,
duration: null,
elapsed: null,
expectedFinish: null,
finishedAt: null,
playback: Playback.Stop,
phase: TimerPhase.None,
secondaryTimer: null,
startedAt: null,
},
} as RuntimeState;
const phase = getTimerPhase(state);
expect(phase).toBe(TimerPhase.None);
});
it('can be negative', () => {
const state = {
timer: {
addedTime: 0,
current: -50,
duration: 1000,
playback: Playback.Play,
},
eventNow: {
timeDanger: 100,
timeWarning: 200,
},
} as RuntimeState;
const phase = getTimerPhase(state);
expect(phase).toBe(TimerPhase.Negative);
});
it('can be danger', () => {
const state = {
timer: {
addedTime: 0,
current: 0,
duration: 1000,
playback: Playback.Play,
},
eventNow: {
timeDanger: 100,
timeWarning: 200,
},
} as RuntimeState;
const phase = getTimerPhase(state);
expect(phase).toBe(TimerPhase.Danger);
});
it('can be warning', () => {
const state = {
timer: {
addedTime: 0,
current: 150,
duration: 1000,
playback: Playback.Play,
},
eventNow: {
timeDanger: 100,
timeWarning: 200,
},
} as RuntimeState;
const phase = getTimerPhase(state);
expect(phase).toBe(TimerPhase.Warning);
});
it('it default if the timer is playing and there is none of the above', () => {
const state = {
timer: {
addedTime: 0,
current: 250,
duration: 1000,
playback: Playback.Play,
},
eventNow: {
timeDanger: 100,
timeWarning: 200,
},
} as RuntimeState;
const phase = getTimerPhase(state);
expect(phase).toBe(TimerPhase.Default);
});
});
+41 -1
View File
@@ -1,4 +1,4 @@
import { MaybeNumber, MaybeString, OntimeEvent, TimerType } from 'ontime-types';
import { MaybeNumber, MaybeString, OntimeEvent, Playback, TimerPhase, TimerType } from 'ontime-types';
import { dayInMs } from 'ontime-utils';
import { RuntimeState } from '../stores/runtimeState.js';
import { timerConfig } from '../config/config.js';
@@ -361,3 +361,43 @@ export function getExpectedEnd(state: RuntimeState): MaybeNumber {
}
return state.runtime.plannedEnd - state.runtime.offset + state._timer.totalDelay;
}
/**
* Utility checks whether the playback is considered to be active
* @param state
* @returns
*/
function isPlaybackActive(state: RuntimeState): boolean {
return (
state.timer.playback === Playback.Play ||
state.timer.playback === Playback.Pause ||
state.timer.playback === Playback.Roll
);
}
/**
* Checks running timer to see which phase it currently is in
* @param state
*/
export function getTimerPhase(state: RuntimeState): TimerPhase {
if (!isPlaybackActive(state)) {
return TimerPhase.None;
}
const current = state.timer.current;
if (current < 0) {
return TimerPhase.Negative;
}
const danger = state.eventNow.timeDanger;
if (current <= danger) {
return TimerPhase.Danger;
}
const warning = state.eventNow.timeWarning;
if (current <= warning) {
return TimerPhase.Warning;
}
return TimerPhase.Default;
}
+10 -1
View File
@@ -1,4 +1,4 @@
import { MaybeNumber, OntimeEvent, Playback, Runtime, TimerState, TimerType } from 'ontime-types';
import { MaybeNumber, OntimeEvent, Playback, Runtime, TimerPhase, TimerState, TimerType } from 'ontime-types';
import { calculateDuration, dayInMs } from 'ontime-utils';
import { clock } from '../services/Clock.js';
@@ -10,6 +10,7 @@ import {
getExpectedFinish,
getRollTimers,
getRuntimeOffset,
getTimerPhase,
skippedOutOfEvent,
updateRoll,
} from '../services/timerUtils.js';
@@ -32,6 +33,7 @@ const initialTimer: TimerState = {
elapsed: null,
expectedFinish: null, // TODO: expected finish could account for midnight, we cleanup in the clients
finishedAt: null,
phase: TimerPhase.None,
playback: Playback.Stop,
secondaryTimer: null,
startedAt: null,
@@ -300,6 +302,10 @@ export function start(state: RuntimeState = runtimeState): boolean {
state.runtime.actualStart = state.clock;
}
// update timer phase
runtimeState.timer.phase = getTimerPhase(runtimeState);
// update offset
state.runtime.offset = getRuntimeOffset(state);
state.runtime.expectedEnd = state.runtime.plannedEnd - state.runtime.offset;
@@ -387,6 +393,9 @@ export function update(): UpdateResult {
runtimeState.timer.duration = runtimeState.timer.current;
}
// update timer phase
runtimeState.timer.phase = getTimerPhase(runtimeState);
// update offset
runtimeState.runtime.offset = getRuntimeOffset(runtimeState);
runtimeState.runtime.expectedEnd = getExpectedEnd(runtimeState);