@@ -5,6 +5,7 @@ import { TimelineObjRundown } from '@sofie-automation/corelib/dist/dataModel/Tim
5
5
import { normalizeArray } from '@sofie-automation/corelib/dist/lib'
6
6
import { PieceTimelineMetadata } from './pieceGroup'
7
7
import { StudioPlayoutModelBase } from '../../studio/model/StudioPlayoutModel'
8
+ import { logger } from '../../logging'
8
9
import { JobContext } from '../../jobs'
9
10
import { getCurrentTime } from '../../lib'
10
11
import { PlayoutModel } from '../model/PlayoutModel'
@@ -46,7 +47,7 @@ export function deNowifyMultiGatewayTimeline(
46
47
playoutModel . nextPartInstance
47
48
)
48
49
49
- deNowifyCurrentPieces (
50
+ const { objectsNotDeNowified } = deNowifyCurrentPieces (
50
51
targetNowTime ,
51
52
timingContext ,
52
53
currentPartInstance ,
@@ -55,6 +56,9 @@ export function deNowifyMultiGatewayTimeline(
55
56
)
56
57
57
58
updatePlannedTimingsForPieceInstances ( playoutModel , currentPartInstance , partGroupTimings , timelineObjsMap )
59
+
60
+ // Because updatePlannedTimingsForPieceInstances changes start times of infinites, we can now run deNowifyInfinites()
61
+ deNowifyInfinites ( targetNowTime , objectsNotDeNowified , timelineObjsMap )
58
62
}
59
63
60
64
/**
@@ -142,16 +146,75 @@ function updatePartInstancePlannedTimes(
142
146
}
143
147
}
144
148
149
+ /**
150
+ * Replace the `now` time in any timeline objects in infinites
151
+ */
152
+ function deNowifyInfinites (
153
+ targetNowTime : number ,
154
+ /** A list of objects that need to be updated */
155
+ infiniteObjs : TimelineObjRundown [ ] ,
156
+ timelineObjsMap : Record < string , TimelineObjRundown >
157
+ ) {
158
+ /**
159
+ * Recursively look up the absolute starttime of a timeline object
160
+ * taking into account its parent's times.
161
+ * Note: This only supports timeline objects that have absolute enable.start times.
162
+ */
163
+ const getStartTime = ( obj : TimelineObjRundown ) : number | undefined => {
164
+ if ( Array . isArray ( obj . enable ) ) return undefined
165
+
166
+ const myStartTime = typeof obj . enable . start === 'number' ? obj . enable . start : undefined
167
+
168
+ if ( ! obj . inGroup ) return myStartTime
169
+
170
+ if ( myStartTime === undefined ) return undefined
171
+
172
+ const parentObject = timelineObjsMap [ obj . inGroup ]
173
+ if ( ! parentObject ) return undefined
174
+
175
+ const parentStartTime = getStartTime ( parentObject )
176
+ if ( parentStartTime === undefined ) return undefined
177
+
178
+ return parentStartTime + myStartTime
179
+ }
180
+
181
+ for ( const obj of infiniteObjs ) {
182
+ if ( ! Array . isArray ( obj . enable ) && obj . enable . start === 'now' ) {
183
+ if ( obj . inGroup ) {
184
+ const parentObject = timelineObjsMap [ obj . inGroup ]
185
+ if ( parentObject ) {
186
+ const parentStartTime = getStartTime ( parentObject )
187
+ if ( parentStartTime !== undefined ) {
188
+ obj . enable = { start : targetNowTime - parentStartTime }
189
+ } else {
190
+ logger . error (
191
+ `Unable to derive an absolute start time of parent "${ obj . inGroup } " for object "${ obj . id } " during deNowifyInfinites`
192
+ )
193
+ }
194
+ } else {
195
+ logger . error ( `Parent obj "${ obj . inGroup } " not found of object "${ obj . id } " during deNowifyInfinites` )
196
+ }
197
+ } else {
198
+ logger . error (
199
+ `Unexpected "now" time during deNowifyInfinites, setting to absolute time for a timelineObject not inGroup: "${ obj . id } "`
200
+ )
201
+ obj . enable = { start : targetNowTime }
202
+ }
203
+ }
204
+ }
205
+ }
145
206
/**
146
207
* Replace the `now` time in any Pieces on the timeline from the current Part with concrete start times
208
+ * @returns a list of object that couldn't be updated at this time.
147
209
*/
148
210
function deNowifyCurrentPieces (
149
211
targetNowTime : number ,
150
212
timingContext : RundownTimelineTimingContext ,
151
213
currentPartInstance : PlayoutPartInstanceModel ,
152
214
currentPartGroupStartTime : number ,
153
215
timelineObjsMap : Record < string , TimelineObjRundown >
154
- ) {
216
+ ) : { objectsNotDeNowified : TimelineObjRundown [ ] } {
217
+ const objectsNotDeNowified : TimelineObjRundown [ ] = [ ]
155
218
// The relative time for 'now' to be resolved to, inside of the part group
156
219
const nowInPart = targetNowTime - currentPartGroupStartTime
157
220
@@ -176,6 +239,8 @@ function deNowifyCurrentPieces(
176
239
obj . enable = { start : nowInPart }
177
240
} else if ( ! obj . inGroup ) {
178
241
obj . enable = { start : targetNowTime }
242
+ } else {
243
+ objectsNotDeNowified . push ( obj )
179
244
}
180
245
}
181
246
}
@@ -203,6 +268,7 @@ function deNowifyCurrentPieces(
203
268
}
204
269
}
205
270
}
271
+ return { objectsNotDeNowified }
206
272
}
207
273
208
274
function updatePlannedTimingsForPieceInstances (
0 commit comments