fix: maintain offset on roll takeover

This commit is contained in:
Carlos Valente
2025-10-05 20:36:00 +02:00
committed by Alex Christoffer Rasmussen
parent 25030debe4
commit a02cdf71c0
3 changed files with 14 additions and 10 deletions
@@ -4,6 +4,7 @@ import {
isOntimeEvent,
isPlayableEvent,
LogOrigin,
Offset,
OffsetMode,
OntimeEvent,
Playback,
@@ -88,18 +89,17 @@ class RuntimeService {
// 2. handle edge cases related to roll
if (newState.timer.playback === Playback.Roll) {
// check if we need to call any side effects
const keepOffset = newState.offset.absolute;
if (hasSecondaryTimerFinished) {
// if the secondary timer has finished, we need to call roll
// since event is already loaded
this.rollLoaded(keepOffset);
this.rollLoaded(newState.offset);
} else if (hasTimerFinished) {
// if the timer has finished, we need to load next and keep rolling
process.nextTick(() => {
triggerAutomations(TimerLifeCycle.onFinish, newState);
});
this.handleLoadNext();
this.rollLoaded(keepOffset);
this.rollLoaded(newState.offset);
} else if (
// if there is no previous clock, we could not have skipped
RuntimeService.previousState?.clock &&
@@ -541,7 +541,7 @@ class RuntimeService {
/**
* Handles special case to call roll on a loaded event which we do not want to discard
*/
private rollLoaded(offset?: number) {
private rollLoaded(offset: Offset) {
const rundown = getCurrentRundown();
const metadata = getRundownMetadata();
@@ -357,18 +357,18 @@ describe('roll mode', () => {
start();
// the current offset after manual play
const currentOffset = getState().offset.absolute;
let result = roll(rundown, metadata, getState().offset.absolute);
let result = roll(rundown, metadata, getState().offset);
expect(result).toStrictEqual({ eventId: '1', didStart: false });
// the current offset should be maintain by roll mode when taking over from play
expect(getState().offset.absolute).toBe(currentOffset);
vi.setSystemTime('jan 1 00:00:01');
result = roll(rundown, metadata, getState().offset.absolute);
result = roll(rundown, metadata, getState().offset);
expect(result).toStrictEqual({ eventId: '2', didStart: true });
expect(getState().offset.absolute).toBe(-1000);
vi.setSystemTime('jan 1 00:00:02');
result = roll(rundown, metadata, getState().offset.absolute);
result = roll(rundown, metadata, getState().offset);
expect(result).toStrictEqual({ eventId: '3', didStart: true });
expect(getState().offset.absolute).toBe(-1000);
+7 -3
View File
@@ -595,7 +595,7 @@ export function update(): UpdateResult {
export function roll(
rundown: Rundown,
metadata: RundownMetadata,
offset = 0,
offset?: Offset,
): { eventId: MaybeString; didStart: boolean } {
// 1. if an event is running, we simply take over the playback
if (runtimeState.timer.playback === Playback.Play && runtimeState.rundown.selectedEventIndex !== null) {
@@ -616,7 +616,9 @@ export function roll(
}
}
runtimeState.offset.absolute = offset;
if (offset) {
runtimeState.offset = { ...offset };
}
runtimeState.timer.playback = Playback.Roll;
// account for event that finishes the day after
@@ -673,7 +675,9 @@ export function roll(
clearEventData();
// account for offset but we only keep it if passed to us
runtimeState.offset.absolute = offset;
if (offset) {
runtimeState.offset = { ...offset };
}
const offsetClock = runtimeState.clock - runtimeState.offset.absolute;
const { index, isPending } = loadRoll(rundown, metadata, offsetClock);