1- import { BlueprintId , RundownPlaylistId , TimelineHash } from '@sofie-automation/corelib/dist/dataModel/Ids'
1+ import { BlueprintId , RundownPlaylistId } from '@sofie-automation/corelib/dist/dataModel/Ids'
22import { JobContext , JobStudio } from '../../jobs/index.js'
33import { ReadonlyDeep } from 'type-fest'
44import { BlueprintResultBaseline , OnGenerateTimelineObj , Time , TSR } from '@sofie-automation/blueprints-integration'
@@ -37,7 +37,6 @@ import { deserializePieceTimelineObjectsBlob } from '@sofie-automation/corelib/d
3737import { convertResolvedPieceInstanceToBlueprints } from '../../blueprints/context/lib.js'
3838import { buildTimelineObjsForRundown , RundownTimelineTimingContext } from './rundown.js'
3939import { SourceLayers } from '@sofie-automation/corelib/dist/dataModel/ShowStyleBase'
40- import { deNowifyMultiGatewayTimeline } from './multi-gateway.js'
4140import { validateTimeline } from 'superfly-timeline'
4241import { getPartTimingsOrDefaults , PartCalculatedTimings } from '@sofie-automation/corelib/dist/playout/timings'
4342import { applyAbPlaybackForTimeline } from '../abPlayback/index.js'
@@ -67,25 +66,19 @@ function generateTimelineVersions(
6766 }
6867}
6968
70- export async function updateStudioTimeline (
69+ /**
70+ * Generate timeline objects for a studio (when no playlist is active)
71+ */
72+ export async function getStudioTimeline (
7173 context : JobContext ,
7274 playoutModel : StudioPlayoutModel | PlayoutModel
73- ) : Promise < void > {
74- const span = context . startSpan ( 'updateStudioTimeline' )
75- logger . debug ( 'updateStudioTimeline running...' )
75+ ) : Promise < {
76+ objs : Array < TimelineObjRundown >
77+ versions : TimelineCompleteGenerationVersions
78+ timingContext : undefined
79+ regenerateTimelineToken : undefined
80+ } > {
7681 const studio = context . studio
77- // Ensure there isn't a playlist active, as that should be using a different function call
78- if ( isModelForStudio ( playoutModel ) ) {
79- const activePlaylists = playoutModel . getActiveRundownPlaylists ( )
80- if ( activePlaylists . length > 0 ) {
81- throw new Error ( `Studio has an active playlist` )
82- }
83- } else {
84- if ( playoutModel . playlist . activationId ) {
85- throw new Error ( `Studio has an active playlist` )
86- }
87- }
88-
8982 let baselineObjects : TimelineObjRundown [ ] = [ ]
9083 let studioBaseline : BlueprintResultBaseline | undefined
9184
@@ -119,60 +112,58 @@ export async function updateStudioTimeline(
119112 studioBlueprint ?. blueprint ?. blueprintVersion ?? '-'
120113 )
121114
122- flattenAndProcessTimelineObjects ( context , baselineObjects )
123-
124- // Future: We should handle any 'now' objects that are at the root of this timeline
125- preserveOrReplaceNowTimesInObjects ( playoutModel , baselineObjects )
126-
127- if ( playoutModel . isMultiGatewayMode ) {
128- logAnyRemainingNowTimes ( context , baselineObjects )
115+ if ( studioBaseline ) {
116+ updateBaselineExpectedPackagesOnStudio ( context , playoutModel , studioBaseline )
129117 }
130118
131- const timelineHash = saveTimeline ( context , playoutModel , baselineObjects , versions , undefined )
119+ return {
120+ objs : baselineObjects ,
121+ versions,
122+ timingContext : undefined ,
123+ regenerateTimelineToken : undefined ,
124+ }
125+ }
132126
133- if ( studioBaseline ) {
134- updateBaselineExpectedPackagesOnStudio ( context , playoutModel , studioBaseline )
127+ export async function updateStudioTimeline (
128+ context : JobContext ,
129+ playoutModel : StudioPlayoutModel | PlayoutModel
130+ ) : Promise < void > {
131+ const span = context . startSpan ( 'updateStudioTimeline' )
132+ logger . debug ( 'updateStudioTimeline: marking studio as needing timeline update' )
133+ // Ensure there isn't a playlist active, as that should be using a different function call
134+ if ( isModelForStudio ( playoutModel ) ) {
135+ const activePlaylists = playoutModel . getActiveRundownPlaylists ( )
136+ if ( activePlaylists . length > 0 ) {
137+ throw new Error ( `Studio has an active playlist` )
138+ }
139+ } else {
140+ if ( playoutModel . playlist . activationId ) {
141+ throw new Error ( `Studio has an active playlist` )
142+ }
135143 }
136144
137- logger . verbose ( `updateStudioTimeline done, hash: "${ timelineHash } "` )
145+ playoutModel . markTimelineNeedsUpdate ( )
146+
138147 if ( span ) span . end ( )
139148}
140149
141150export async function updateTimeline ( context : JobContext , playoutModel : PlayoutModel ) : Promise < void > {
142151 const span = context . startSpan ( 'updateTimeline' )
143- logger . debug ( 'updateTimeline running... ' )
152+ logger . debug ( 'updateTimeline: marking playlist as needing timeline update ' )
144153
145154 if ( ! playoutModel . playlist . activationId ) {
146155 throw new Error ( `RundownPlaylist ("${ playoutModel . playlist . _id } ") is not active")` )
147156 }
148157
149- const {
150- versions,
151- objs : timelineObjs ,
152- timingContext : timingInfo ,
153- regenerateTimelineToken,
154- } = await getTimelineRundown ( context , playoutModel )
155-
156- flattenAndProcessTimelineObjects ( context , timelineObjs )
157-
158- preserveOrReplaceNowTimesInObjects ( playoutModel , timelineObjs )
159-
160- if ( playoutModel . isMultiGatewayMode ) {
161- deNowifyMultiGatewayTimeline ( playoutModel , timelineObjs , timingInfo )
162-
163- logAnyRemainingNowTimes ( context , timelineObjs )
164- }
165-
166- const timelineHash = saveTimeline ( context , playoutModel , timelineObjs , versions , regenerateTimelineToken )
167- logger . verbose ( `updateTimeline done, hash: "${ timelineHash } "` )
158+ playoutModel . markTimelineNeedsUpdate ( )
168159
169160 if ( span ) span . end ( )
170161}
171162
172- function preserveOrReplaceNowTimesInObjects (
163+ export function preserveOrReplaceNowTimesInObjects (
173164 studioPlayoutModel : StudioPlayoutModelBase ,
174165 timelineObjs : Array < TimelineObjGeneric >
175- ) {
166+ ) : void {
176167 const timeline = studioPlayoutModel . timeline
177168 const oldTimelineObjsMap = normalizeArray (
178169 ( timeline ?. timelineBlob !== undefined && deserializeTimelineBlob ( timeline . timelineBlob ) ) || [ ] ,
@@ -202,7 +193,7 @@ function preserveOrReplaceNowTimesInObjects(
202193 } )
203194}
204195
205- function logAnyRemainingNowTimes ( _context : JobContext , timelineObjs : Array < TimelineObjGeneric > ) : void {
196+ export function logAnyRemainingNowTimes ( _context : JobContext , timelineObjs : Array < TimelineObjGeneric > ) : void {
206197 const badTimelineObjs : any [ ] = [ ]
207198
208199 for ( const obj of timelineObjs ) {
@@ -229,22 +220,6 @@ function hasNow(obj: TimelineEnableExt | TimelineEnableExt[]) {
229220 return res
230221}
231222
232- /** Store the timelineobjects into the model, and perform any post-save actions */
233- export function saveTimeline (
234- context : JobContext ,
235- studioPlayoutModel : StudioPlayoutModelBase ,
236- timelineObjs : TimelineObjGeneric [ ] ,
237- generationVersions : TimelineCompleteGenerationVersions ,
238- regenerateTimelineToken : string | undefined
239- ) : TimelineHash {
240- const newTimeline = studioPlayoutModel . setTimeline ( timelineObjs , generationVersions , regenerateTimelineToken )
241-
242- // Also do a fast-track for the timeline to be published faster:
243- context . hackPublishTimelineToFastTrack ( newTimeline )
244-
245- return newTimeline . timelineHash
246- }
247-
248223export interface SelectedPartInstancesTimelineInfo {
249224 previous ?: SelectedPartInstanceTimelineInfo
250225 current ?: SelectedPartInstanceTimelineInfo
@@ -303,7 +278,7 @@ function getPartInstanceTimelineInfo(
303278/**
304279 * Returns timeline objects related to rundowns in a studio
305280 */
306- async function getTimelineRundown (
281+ export async function getTimelineRundown (
307282 context : JobContext ,
308283 playoutModel : PlayoutModel
309284) : Promise < {
@@ -562,7 +537,7 @@ function createRegenerateTimelineObj(
562537 * @param context
563538 * @param timelineObjs Array of timeline objects
564539 */
565- function flattenAndProcessTimelineObjects ( context : JobContext , timelineObjs : Array < TimelineObjGeneric > ) : void {
540+ export function flattenAndProcessTimelineObjects ( context : JobContext , timelineObjs : Array < TimelineObjGeneric > ) : void {
566541 const span = context . startSpan ( 'processTimelineObjects' )
567542
568543 // first, split out any grouped objects, to make the timeline shallow:
0 commit comments