Skip to content

Commit 52ede26

Browse files
author
Mint de Wit
committed
fix: reset segments when added to an active loop
1 parent e560a4c commit 52ede26

File tree

4 files changed

+108
-2
lines changed

4 files changed

+108
-2
lines changed

packages/job-worker/src/playout/model/PlayoutModel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ export interface PlayoutModel extends PlayoutModelReadonly, StudioPlayoutModelBa
335335
*/
336336
setQuickLoopMarker(type: 'start' | 'end', marker: QuickLoopMarker | null): void
337337

338+
getSegmentsBetweenQuickLoopMarker(start: QuickLoopMarker, end: QuickLoopMarker): SegmentId[]
339+
338340
calculatePartTimings(
339341
fromPartInstance: PlayoutPartInstanceModel | null,
340342
toPartInstance: PlayoutPartInstanceModel,

packages/job-worker/src/playout/model/implementation/PlayoutModelImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,10 @@ export class PlayoutModelImpl extends PlayoutModelReadonlyImpl implements Playou
788788
this.#playlistHasChanged = true
789789
}
790790

791+
getSegmentsBetweenQuickLoopMarker(start: QuickLoopMarker, end: QuickLoopMarker): SegmentId[] {
792+
return this.quickLoopService.getSegmentsBetweenMarkers(start, end)
793+
}
794+
791795
/** Lifecycle */
792796

793797
/** @deprecated */

packages/job-worker/src/playout/model/services/QuickLoopService.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
99
import { ReadonlyObjectDeep } from 'type-fest/source/readonly-deep'
1010
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
11-
import { RundownId } from '@sofie-automation/corelib/dist/dataModel/Ids'
11+
import { RundownId, SegmentId } from '@sofie-automation/corelib/dist/dataModel/Ids'
1212
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
1313
import { PlayoutPartInstanceModel } from '../PlayoutPartInstanceModel'
1414
import { JobContext } from '../../../jobs'
@@ -149,6 +149,38 @@ export class QuickLoopService {
149149
return quickLoopProps
150150
}
151151

152+
getSegmentsBetweenMarkers(startMarker: QuickLoopMarker, endMarker: QuickLoopMarker): SegmentId[] {
153+
const orderedParts = this.playoutModel.getAllOrderedParts()
154+
const rundownIds = this.playoutModel.getRundownIds()
155+
156+
const start = this.findQuickLoopMarkerPosition(startMarker, 'start', orderedParts, rundownIds)
157+
const end = this.findQuickLoopMarkerPosition(endMarker, 'end', orderedParts, rundownIds)
158+
159+
if (this.areMarkersFlipped(start, end)) return []
160+
161+
const segmentIds: Set<SegmentId> = new Set()
162+
163+
for (const part of orderedParts) {
164+
const currentSegment = this.playoutModel.findSegment(part.segmentId)?.segment
165+
const currentRundownIndex = rundownIds.findIndex((id) => id === part.rundownId)
166+
167+
if (!currentSegment) continue // ???
168+
169+
if (
170+
currentRundownIndex >= start.rundownRank &&
171+
currentRundownIndex <= end.rundownRank &&
172+
currentSegment._rank >= start.segmentRank &&
173+
currentSegment._rank <= end.segmentRank &&
174+
part._rank >= start.partRank &&
175+
part._rank <= start.partRank
176+
) {
177+
segmentIds.add(currentSegment._id)
178+
}
179+
}
180+
181+
return Array.from(segmentIds.values())
182+
}
183+
152184
private areMarkersFlipped(startPosition: MarkerPosition, endPosition: MarkerPosition) {
153185
return compareMarkerPositions(startPosition, endPosition) < 0
154186
}

packages/job-worker/src/playout/quickLoopMarkers.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { runJobWithPlayoutModel } from './lock'
55
import { updateTimeline } from './timeline/generate'
66
import { selectNextPart } from './selectNextPart'
77
import { setNextPart } from './setNext'
8+
import { resetPartInstancesWithPieceInstances } from './lib'
9+
import { QuickLoopMarker, QuickLoopMarkerType } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
10+
import { SegmentId } from '@sofie-automation/corelib/dist/dataModel/Ids'
811

912
export async function handleSetQuickLoopMarker(context: JobContext, data: SetQuickLoopMarkerProps): Promise<void> {
1013
return runJobWithPlayoutModel(
@@ -17,9 +20,74 @@ export async function handleSetQuickLoopMarker(context: JobContext, data: SetQui
1720
async (playoutModel) => {
1821
const playlist = playoutModel.playlist
1922
if (!playlist.activationId) throw new Error(`Playlist has no activationId!`)
20-
const wasQuickLoopRunning = playoutModel.playlist.quickLoop?.running
23+
const oldProps = playoutModel.playlist.quickLoop
24+
const wasQuickLoopRunning = oldProps?.running
2125
playoutModel.setQuickLoopMarker(data.type, data.marker)
2226

27+
const markerChanged = (
28+
markerA: QuickLoopMarker | undefined,
29+
markerB: QuickLoopMarker | undefined
30+
): boolean => {
31+
if (!markerA || !markerB) return false
32+
33+
if (
34+
(markerA.type === QuickLoopMarkerType.RUNDOWN ||
35+
markerA.type === QuickLoopMarkerType.SEGMENT ||
36+
markerA.type === QuickLoopMarkerType.PART) &&
37+
(markerB.type === QuickLoopMarkerType.RUNDOWN ||
38+
markerB.type === QuickLoopMarkerType.SEGMENT ||
39+
markerB.type === QuickLoopMarkerType.PART)
40+
) {
41+
return markerA.id !== markerB.id
42+
}
43+
44+
return false
45+
}
46+
47+
if (playlist.currentPartInfo) {
48+
// rundown is on air
49+
let segmentsToReset: SegmentId[] = []
50+
51+
if (
52+
playlist.quickLoop?.start &&
53+
oldProps?.start &&
54+
markerChanged(oldProps.start, playlist.quickLoop.start)
55+
) {
56+
// start marker changed
57+
segmentsToReset = playoutModel.getSegmentsBetweenQuickLoopMarker(
58+
playlist.quickLoop.start,
59+
oldProps.start
60+
)
61+
} else if (
62+
playlist.quickLoop?.end &&
63+
oldProps?.end &&
64+
markerChanged(oldProps.end, playlist.quickLoop.end)
65+
) {
66+
// end marker changed
67+
segmentsToReset = playoutModel.getSegmentsBetweenQuickLoopMarker(
68+
oldProps.end,
69+
playlist.quickLoop.end
70+
)
71+
} else if (playlist.quickLoop?.start && playlist.quickLoop.end && !(oldProps?.start && oldProps.end)) {
72+
// a new loop was created
73+
segmentsToReset = playoutModel.getSegmentsBetweenQuickLoopMarker(
74+
playlist.quickLoop.start,
75+
playlist.quickLoop.end
76+
)
77+
}
78+
79+
// reset segments that have been added to the loop and are not on-air
80+
resetPartInstancesWithPieceInstances(context, playoutModel, {
81+
segmentId: {
82+
$in: segmentsToReset.filter(
83+
(segmentId) =>
84+
segmentId !== playoutModel.currentPartInstance?.partInstance.segmentId &&
85+
segmentId !== playoutModel.nextPartInstance?.partInstance.segmentId
86+
),
87+
},
88+
})
89+
}
90+
2391
if (wasQuickLoopRunning) {
2492
const nextPart = selectNextPart(
2593
context,

0 commit comments

Comments
 (0)