fix: handle finish when adding time

This commit is contained in:
Carlos Valente
2024-05-18 22:16:34 +02:00
committed by Carlos Valente
parent cfbd540a14
commit 082449bede
+18 -7
View File
@@ -47,6 +47,7 @@ export type RuntimeState = {
timer: TimerState;
// private properties of the timer calculations
_timer: {
forceFinish: MaybeNumber;
totalDelay: number; // this value comes from rundown service
pausedAt: MaybeNumber;
secondaryTarget: MaybeNumber;
@@ -62,6 +63,7 @@ const runtimeState: RuntimeState = {
runtime: { ...initialRuntime },
timer: { ...initialTimer },
_timer: {
forceFinish: null,
totalDelay: 0,
pausedAt: null,
secondaryTarget: null,
@@ -331,15 +333,14 @@ export function addTime(amount: number) {
return false;
}
runtimeState.timer.addedTime += amount;
runtimeState.timer.expectedFinish += amount;
runtimeState.timer.current += amount;
// handle edge cases
// !!! we need to handle side effects before updating the state
const willGoNegative = amount < 0 && Math.abs(amount) > runtimeState.timer.current;
const hasFinished = runtimeState.timer.finishedAt !== null;
if (willGoNegative && !hasFinished) {
runtimeState.timer.finishedAt = clock.timeNow();
// set finished time so side effects are triggered
runtimeState._timer.forceFinish = clock.timeNow();
} else {
const willGoPositive = runtimeState.timer.current < 0 && runtimeState.timer.current + amount > 0;
if (willGoPositive) {
@@ -347,6 +348,11 @@ export function addTime(amount: number) {
}
}
// we can update the state after handling the side effects
runtimeState.timer.addedTime += amount;
runtimeState.timer.expectedFinish += amount;
runtimeState.timer.current += amount;
// update runtime delays: over - under
runtimeState.runtime.offset = getRuntimeOffset(runtimeState);
runtimeState.runtime.expectedEnd = getExpectedEnd(runtimeState);
@@ -405,16 +411,21 @@ export function update(): UpdateResult {
function onPlayUpdate() {
let isFinished = false;
runtimeState.timer.current = getCurrent(runtimeState);
const shouldForceFinish = runtimeState._timer.forceFinish !== null;
const finishedNow =
runtimeState.timer.current <= timerConfig.triggerAhead && runtimeState.timer.finishedAt === null;
shouldForceFinish ||
(runtimeState.timer.current <= timerConfig.triggerAhead && runtimeState.timer.finishedAt === null);
if (runtimeState.timer.playback === Playback.Play && finishedNow) {
runtimeState.timer.finishedAt = runtimeState.clock;
runtimeState.timer.finishedAt = runtimeState._timer.forceFinish ?? runtimeState.clock;
isFinished = true;
} else {
runtimeState.timer.expectedFinish = getExpectedFinish(runtimeState);
}
if (shouldForceFinish) {
runtimeState._timer.forceFinish = null;
}
runtimeState.timer.elapsed = runtimeState.timer.duration - runtimeState.timer.current;
return { isFinished };