mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 15:09:10 +00:00
refactor(roll breaking): make starting with roll backtrace planned times
This commit is contained in:
committed by
Carlos Valente
parent
d04f958c11
commit
00aa8a09fa
@@ -230,7 +230,6 @@ export const useOffsetOverview = createSelector((state: RuntimeStore) => ({
|
|||||||
|
|
||||||
export const useGroupTimerOverView = createSelector((state: RuntimeStore) => ({
|
export const useGroupTimerOverView = createSelector((state: RuntimeStore) => ({
|
||||||
clock: state.clock,
|
clock: state.clock,
|
||||||
offset: state.offset.mode === OffsetMode.Absolute ? state.offset.absolute : state.offset.relative,
|
|
||||||
mode: state.offset.mode,
|
mode: state.offset.mode,
|
||||||
groupExpectedEnd: state.offset.expectedGroupEnd,
|
groupExpectedEnd: state.offset.expectedGroupEnd,
|
||||||
// we can force these numbers to 0 fo this use case to avoid null checks
|
// we can force these numbers to 0 fo this use case to avoid null checks
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ export function MetadataTimes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function GroupTimes() {
|
function GroupTimes() {
|
||||||
const { clock, groupExpectedEnd, actualGroupStart, mode, playback, currentDay } = useGroupTimerOverView();
|
const { clock, mode, groupExpectedEnd, actualGroupStart, currentDay, playback } = useGroupTimerOverView();
|
||||||
const { currentGroupId } = useCurrentGroupId();
|
const { currentGroupId } = useCurrentGroupId();
|
||||||
const group = useEntry(currentGroupId) as OntimeGroup | null;
|
const group = useEntry(currentGroupId) as OntimeGroup | null;
|
||||||
|
|
||||||
@@ -111,6 +111,7 @@ function GroupTimes() {
|
|||||||
if (!active) return null;
|
if (!active) return null;
|
||||||
if (!group || group.timeStart === null) return null;
|
if (!group || group.timeStart === null) return null;
|
||||||
const normalizedClock = clock + currentDay * dayInMs;
|
const normalizedClock = clock + currentDay * dayInMs;
|
||||||
|
|
||||||
return mode === OffsetMode.Absolute
|
return mode === OffsetMode.Absolute
|
||||||
? group.timeStart + group.duration - normalizedClock
|
? group.timeStart + group.duration - normalizedClock
|
||||||
: actualGroupStart + group.duration - normalizedClock;
|
: actualGroupStart + group.duration - normalizedClock;
|
||||||
@@ -121,11 +122,9 @@ function GroupTimes() {
|
|||||||
const expectedGroupEnd = groupExpectedEnd !== null ? groupExpectedEnd - clock : null;
|
const expectedGroupEnd = groupExpectedEnd !== null ? groupExpectedEnd - clock : null;
|
||||||
const expectedTimeUntilGroupEnd = formatDueTime(expectedGroupEnd, 3, TimerType.CountDown);
|
const expectedTimeUntilGroupEnd = formatDueTime(expectedGroupEnd, 3, TimerType.CountDown);
|
||||||
|
|
||||||
const groupTitle = group?.title ?? null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.metadataRow}>
|
<div className={style.metadataRow}>
|
||||||
<span className={groupTitle ? style.labelTitle : style.label}>{`${groupTitle || 'Group'} `}</span>
|
<span className={group?.title ? style.labelTitle : style.label}>{`${group?.title || 'Group'} `}</span>
|
||||||
<div className={style.labelledElement}>
|
<div className={style.labelledElement}>
|
||||||
<Tooltip text='Time to planned group end' render={<TbFolderPin className={style.icon} />} />
|
<Tooltip text='Time to planned group end' render={<TbFolderPin className={style.icon} />} />
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { MaybeNumber, TimerPhase } from 'ontime-types';
|
import { MaybeNumber, TimerPhase } from 'ontime-types';
|
||||||
import { dayInMs, isPlaybackActive, MILLIS_PER_HOUR } from 'ontime-utils';
|
import { dayInMs, isPlaybackActive, MILLIS_PER_HOUR } from 'ontime-utils';
|
||||||
|
|
||||||
import type { RuntimeState } from '../stores/runtimeState.js';
|
import type { RuntimeState } from '../stores/runtimeState.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,7 +132,7 @@ export function getRuntimeOffset(state: RuntimeState): { absolute: number; relat
|
|||||||
if (actualStart === null) throw new Error('timerUtils.getRuntimeOffset: state.rundown.plannedStart must be set');
|
if (actualStart === null) throw new Error('timerUtils.getRuntimeOffset: state.rundown.plannedStart must be set');
|
||||||
}
|
}
|
||||||
|
|
||||||
// difference between planned event start and actual event start (will be positive if we started behind )
|
// difference between planned event start and actual event start (will be positive if we started behind)
|
||||||
const eventStartOffset = startedAt + _startDayOffset * dayInMs - (timeStart + dayOffset * dayInMs);
|
const eventStartOffset = startedAt + _startDayOffset * dayInMs - (timeStart + dayOffset * dayInMs);
|
||||||
|
|
||||||
// how long has the event been running over (is a negative number when in over timer so inverted before adding to offset)
|
// how long has the event been running over (is a negative number when in over timer so inverted before adding to offset)
|
||||||
@@ -140,9 +141,10 @@ export function getRuntimeOffset(state: RuntimeState): { absolute: number; relat
|
|||||||
// time the playback was paused, the different from now to when we paused is added to the offset TODO: brakes when crossing midnight
|
// time the playback was paused, the different from now to when we paused is added to the offset TODO: brakes when crossing midnight
|
||||||
const pausedTime = state._timer.pausedAt === null ? 0 : clock - state._timer.pausedAt;
|
const pausedTime = state._timer.pausedAt === null ? 0 : clock - state._timer.pausedAt;
|
||||||
|
|
||||||
|
// absolute offset is difference between schedule and playback time
|
||||||
const absolute = eventStartOffset + overtime + pausedTime + addedTime;
|
const absolute = eventStartOffset + overtime + pausedTime + addedTime;
|
||||||
|
|
||||||
// the relative offset is the same as the absolute offset but adjusted relative to the actual start time
|
// the relative offset is the same as the absolute but adjusted relative to the actual start time
|
||||||
const relative = absolute + plannedStart - actualStart - _startDayOffset * dayInMs;
|
const relative = absolute + plannedStart - actualStart - _startDayOffset * dayInMs;
|
||||||
|
|
||||||
// in case of count to end, the absolute offset is just the overtime
|
// in case of count to end, the absolute offset is just the overtime
|
||||||
|
|||||||
@@ -637,15 +637,21 @@ export function roll(
|
|||||||
// check if the event is ready to start or if needs to be pending
|
// check if the event is ready to start or if needs to be pending
|
||||||
const isNow = checkIsNow(runtimeState.eventNow.timeStart, runtimeState.eventNow.timeEnd, offsetClock);
|
const isNow = checkIsNow(runtimeState.eventNow.timeStart, runtimeState.eventNow.timeEnd, offsetClock);
|
||||||
if (isNow) {
|
if (isNow) {
|
||||||
runtimeState.timer.startedAt = runtimeState.clock;
|
/**
|
||||||
|
* If we are starting an event in roll mode
|
||||||
|
* we backtrace all the start times to the supposed start time of the event
|
||||||
|
*/
|
||||||
|
const plannedStart = runtimeState.eventNow.timeStart;
|
||||||
|
runtimeState.timer.startedAt = plannedStart;
|
||||||
|
// reset the secondary timer to cancel any countdowns
|
||||||
runtimeState.timer.secondaryTimer = null;
|
runtimeState.timer.secondaryTimer = null;
|
||||||
|
|
||||||
if (runtimeState.groupNow !== null && runtimeState.rundown.actualGroupStart === null) {
|
if (runtimeState.groupNow !== null && runtimeState.rundown.actualGroupStart === null) {
|
||||||
runtimeState.rundown.actualGroupStart = runtimeState.clock;
|
runtimeState.rundown.actualGroupStart = plannedStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runtimeState.rundown.actualStart === null) {
|
if (runtimeState.rundown.actualStart === null) {
|
||||||
runtimeState.rundown.actualStart = runtimeState.clock;
|
runtimeState.rundown.actualStart = plannedStart;
|
||||||
runtimeState._startDayOffset = 0;
|
runtimeState._startDayOffset = 0;
|
||||||
runtimeState._startEpoch = epoch;
|
runtimeState._startEpoch = epoch;
|
||||||
}
|
}
|
||||||
@@ -703,29 +709,31 @@ export function roll(
|
|||||||
return { eventId: runtimeState.eventNow.id, didStart: false };
|
return { eventId: runtimeState.eventNow.id, didStart: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is something to run, load event
|
/**
|
||||||
// event will finish on time
|
* At this point we know that there is something to run and the event is loaded
|
||||||
// account for event that finishes the day after
|
* - ensure the event will finish ontime
|
||||||
|
* - account for events that finish the day after
|
||||||
|
*
|
||||||
|
* when we start in roll mode
|
||||||
|
* we need to backtrace all times to the supposed start time of the event
|
||||||
|
*/
|
||||||
|
const plannedStart = runtimeState.eventNow.timeStart;
|
||||||
const endTime =
|
const endTime =
|
||||||
runtimeState.eventNow.timeEnd < runtimeState.eventNow.timeStart
|
runtimeState.eventNow.timeEnd < runtimeState.eventNow.timeStart
|
||||||
? runtimeState.eventNow.timeEnd + dayInMs
|
? runtimeState.eventNow.timeEnd + dayInMs
|
||||||
: runtimeState.eventNow.timeEnd;
|
: runtimeState.eventNow.timeEnd;
|
||||||
runtimeState.timer.startedAt = runtimeState.clock;
|
runtimeState.timer.startedAt = plannedStart;
|
||||||
runtimeState.timer.expectedFinish = endTime;
|
runtimeState.timer.expectedFinish = endTime;
|
||||||
|
|
||||||
// we add time to allow timer to catch up
|
|
||||||
runtimeState.timer.addedTime = -(runtimeState.clock - runtimeState.eventNow.timeStart);
|
|
||||||
|
|
||||||
// state catch up
|
// state catch up
|
||||||
runtimeState.timer.duration = calculateDuration(runtimeState.eventNow.timeStart, endTime);
|
runtimeState.timer.duration = calculateDuration(runtimeState.eventNow.timeStart, endTime);
|
||||||
runtimeState.timer.current = getCurrent(runtimeState);
|
runtimeState.timer.current = getCurrent(runtimeState);
|
||||||
runtimeState.timer.elapsed = 0;
|
runtimeState.timer.elapsed = 0;
|
||||||
|
|
||||||
// update runtime
|
// update runtime
|
||||||
runtimeState.rundown.actualStart = runtimeState.clock;
|
runtimeState.rundown.actualStart = plannedStart;
|
||||||
|
|
||||||
if (runtimeState.groupNow !== null && runtimeState.rundown.actualGroupStart === null) {
|
if (runtimeState.groupNow !== null && runtimeState.rundown.actualGroupStart === null) {
|
||||||
runtimeState.rundown.actualGroupStart = runtimeState.clock;
|
runtimeState.rundown.actualGroupStart = plannedStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update metadata
|
// update metadata
|
||||||
|
|||||||
Reference in New Issue
Block a user