Skip to content

Commit 49429ea

Browse files
committed
wip: first draft
1 parent d6ef069 commit 49429ea

File tree

8 files changed

+93
-24
lines changed

8 files changed

+93
-24
lines changed

packages/blueprints-integration/src/api/showStyle.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ export interface ShowStyleBlueprintManifest<TRawConfig = IBlueprintConfig, TProc
112112
context: ISyncIngestUpdateToPartInstanceContext,
113113
existingPartInstance: BlueprintSyncIngestPartInstance,
114114
newData: BlueprintSyncIngestNewData,
115-
116115
playoutStatus: 'previous' | 'current' | 'next'
117116
) => void
118117

@@ -123,7 +122,6 @@ export interface ShowStyleBlueprintManifest<TRawConfig = IBlueprintConfig, TProc
123122
*/
124123
executeDataStoreAction?: (
125124
context: IDataStoreActionExecutionContext,
126-
playoutPersistentState: BlueprintPlayoutPersistentStore<TimelinePersistentState>,
127125
actionId: string,
128126
userData: ActionUserData,
129127
triggerMode?: string
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { TimelinePersistentState } from '@sofie-automation/blueprints-integration'
2+
import type { BlueprintPlayoutPersistentStore } from '@sofie-automation/blueprints-integration/dist/context/playoutStore'
3+
import { clone } from '@sofie-automation/corelib/dist/lib'
4+
5+
export class PersistentPlayoutStateStore implements BlueprintPlayoutPersistentStore {
6+
#state: TimelinePersistentState | undefined
7+
#hasChanges = false
8+
9+
get hasChanges(): boolean {
10+
return this.#hasChanges
11+
}
12+
13+
constructor(state: TimelinePersistentState | undefined) {
14+
this.#state = clone(state)
15+
}
16+
17+
getAll(): Partial<unknown> {
18+
return this.#state || {}
19+
}
20+
getKey<K extends never>(k: K): unknown {
21+
return this.#state?.[k]
22+
}
23+
setKey<K extends never>(k: K, v: unknown): void {
24+
if (!this.#state) this.#state = {}
25+
;(this.#state as any)[k] = v
26+
this.#hasChanges = true
27+
}
28+
setAll(obj: unknown): void {
29+
this.#state = obj
30+
this.#hasChanges = true
31+
}
32+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { convertNoteToNotification } from '../notifications/util'
3434
import type { INoteBase } from '@sofie-automation/corelib/dist/dataModel/Notes'
3535
import { NotificationsModelHelper } from '../notifications/NotificationsModelHelper'
3636
import type { INotificationsModel } from '../notifications/NotificationsModel'
37+
import { PersistentPlayoutStateStore } from '../blueprints/context/services/PersistantStateStore'
3738

3839
/**
3940
* Execute an AdLib Action
@@ -230,15 +231,22 @@ export async function executeActionInner(
230231
)
231232

232233
try {
234+
const blueprintPersistentState = new PersistentPlayoutStateStore(playoutModel.playlist.previousPersistentState)
235+
233236
await blueprint.blueprint.executeAction(
234237
actionContext,
238+
blueprintPersistentState,
235239
actionParameters.actionId,
236240
actionParameters.userData,
237241
actionParameters.triggerMode,
238242
actionParameters.privateData,
239243
actionParameters.publicData,
240244
actionParameters.actionOptions ?? {}
241245
)
246+
247+
if (blueprintPersistentState.hasChanges) {
248+
playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll())
249+
}
242250
} catch (err) {
243251
logger.error(`Error in showStyleBlueprint.executeAction: ${stringifyError(err)}`)
244252
throw UserError.fromUnknown(err)

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,17 +317,21 @@ export interface PlayoutModel extends PlayoutModelReadonly, StudioPlayoutModelBa
317317
setHoldState(newState: RundownHoldState): void
318318

319319
/**
320-
* Store the persistent results of the AB playback resolving and onTimelineGenerate
321-
* @param persistentState Blueprint owned state from onTimelineGenerate
320+
* Store the persistent results of the AB playback resolving
322321
* @param assignedAbSessions The applied AB sessions
323322
* @param trackedAbSessions The known AB sessions
324323
*/
325-
setOnTimelineGenerateResult(
326-
persistentState: unknown | undefined,
324+
setAbResolvingState(
327325
assignedAbSessions: Record<string, ABSessionAssignments>,
328326
trackedAbSessions: ABSessionInfo[]
329327
): void
330328

329+
/**
330+
* Store the blueprint persistent state
331+
* @param persistentState Blueprint owned state
332+
*/
333+
setBlueprintPersistentState(persistentState: unknown | undefined): void
334+
331335
/**
332336
* Set a PartInstance as the nexted PartInstance
333337
* @param partInstance PartInstance to be set as next, or none

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,18 +727,22 @@ export class PlayoutModelImpl extends PlayoutModelReadonlyImpl implements Playou
727727
this.#playlistHasChanged = true
728728
}
729729

730-
setOnTimelineGenerateResult(
731-
persistentState: unknown | undefined,
730+
setAbResolvingState(
732731
assignedAbSessions: Record<string, ABSessionAssignments>,
733732
trackedAbSessions: ABSessionInfo[]
734733
): void {
735-
this.playlistImpl.previousPersistentState = persistentState
736734
this.playlistImpl.assignedAbSessions = assignedAbSessions
737735
this.playlistImpl.trackedAbSessions = trackedAbSessions
738736

739737
this.#playlistHasChanged = true
740738
}
741739

740+
setBlueprintPersistentState(persistentState: unknown | undefined): void {
741+
this.playlistImpl.previousPersistentState = persistentState
742+
743+
this.#playlistHasChanged = true
744+
}
745+
742746
setPartInstanceAsNext(
743747
partInstance: PlayoutPartInstanceModel | null,
744748
setManually: boolean,

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
} from '../blueprints/context/services/PartAndPieceInstanceActionService'
3232
import { NoteSeverity } from '@sofie-automation/blueprints-integration'
3333
import { convertNoteToNotification } from '../notifications/util'
34+
import { PersistentPlayoutStateStore } from '../blueprints/context/services/PersistantStateStore'
3435

3536
/**
3637
* Set or clear the nexted part, from a given PartInstance, or SelectNextPartResult
@@ -225,9 +226,15 @@ async function executeOnSetAsNextCallback(
225226
playoutModel.clearAllNotifications(NOTIFICATION_CATEGORY)
226227

227228
try {
228-
await blueprint.blueprint.onSetAsNext(onSetAsNextContext)
229+
const blueprintPersistentState = new PersistentPlayoutStateStore(playoutModel.playlist.previousPersistentState)
230+
231+
await blueprint.blueprint.onSetAsNext(onSetAsNextContext, blueprintPersistentState)
229232
await applyOnSetAsNextSideEffects(context, playoutModel, onSetAsNextContext)
230233

234+
if (blueprintPersistentState.hasChanges) {
235+
playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll())
236+
}
237+
231238
for (const note of onSetAsNextContext.notes) {
232239
// Update the notifications. Even though these are related to a partInstance, they will be cleared on the next take
233240
playoutModel.setNotification(NOTIFICATION_CATEGORY, {

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
} from '../blueprints/context/services/PartAndPieceInstanceActionService'
3535
import { PlayoutRundownModel } from './model/PlayoutRundownModel'
3636
import { convertNoteToNotification } from '../notifications/util'
37+
import { PersistentPlayoutStateStore } from '../blueprints/context/services/PersistantStateStore'
3738

3839
/**
3940
* Take the currently Next:ed Part (start playing it)
@@ -316,10 +317,18 @@ async function executeOnTakeCallback(
316317
new PartAndPieceInstanceActionService(context, playoutModel, showStyle, currentRundown)
317318
)
318319
try {
319-
await blueprint.blueprint.onTake(onSetAsNextContext)
320+
const blueprintPersistentState = new PersistentPlayoutStateStore(
321+
playoutModel.playlist.previousPersistentState
322+
)
323+
324+
await blueprint.blueprint.onTake(onSetAsNextContext, blueprintPersistentState)
320325
await applyOnTakeSideEffects(context, playoutModel, onSetAsNextContext)
321326
isTakeAborted = onSetAsNextContext.isTakeAborted
322327

328+
if (blueprintPersistentState.hasChanges) {
329+
playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll())
330+
}
331+
323332
for (const note of onSetAsNextContext.notes) {
324333
// Update the notifications. Even though these are related to a partInstance, they will be cleared on the next take
325334
playoutModel.setNotification(NOTIFICATION_CATEGORY, {
@@ -511,13 +520,19 @@ export function updatePartInstanceOnTake(
511520
context.getShowStyleBlueprintConfig(showStyle),
512521
takeRundown
513522
)
523+
const blueprintPersistentState = new PersistentPlayoutStateStore(
524+
playoutModel.playlist.previousPersistentState
525+
)
514526
previousPartEndState = blueprint.blueprint.getEndStateForPart(
515527
context2,
516-
playoutModel.playlist.previousPersistentState,
528+
blueprintPersistentState,
517529
convertPartInstanceToBlueprints(currentPartInstance.partInstance),
518530
resolvedPieces.map(convertResolvedPieceInstanceToBlueprints),
519531
time
520532
)
533+
if (blueprintPersistentState.hasChanges) {
534+
playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll())
535+
}
521536
if (span) span.end()
522537
logger.info(`Calculated end state in ${getCurrentTime() - time}ms`)
523538
} catch (err) {

packages/job-worker/src/playout/timeline/generate.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { BlueprintId, TimelineHash } from '@sofie-automation/corelib/dist/dataModel/Ids'
22
import { JobContext, JobStudio } from '../../jobs'
33
import { ReadonlyDeep } from 'type-fest'
4-
import {
5-
BlueprintResultBaseline,
6-
BlueprintResultTimeline,
7-
OnGenerateTimelineObj,
8-
Time,
9-
TSR,
10-
} from '@sofie-automation/blueprints-integration'
4+
import { BlueprintResultBaseline, OnGenerateTimelineObj, Time, TSR } from '@sofie-automation/blueprints-integration'
115
import {
126
deserializeTimelineBlob,
137
OnGenerateTimelineObjExt,
@@ -46,6 +40,7 @@ import { getPartTimingsOrDefaults, PartCalculatedTimings } from '@sofie-automati
4640
import { applyAbPlaybackForTimeline } from '../abPlayback'
4741
import { stringifyError } from '@sofie-automation/shared-lib/dist/lib/stringifyError'
4842
import { PlayoutPartInstanceModel } from '../model/PlayoutPartInstanceModel'
43+
import { PersistentPlayoutStateStore } from '../../blueprints/context/services/PersistantStateStore'
4944

5045
function isModelForStudio(model: StudioPlayoutModelBase): model is StudioPlayoutModel {
5146
const tmp = model as StudioPlayoutModel
@@ -388,14 +383,17 @@ async function getTimelineRundown(
388383
})
389384
}
390385

391-
let tlGenRes: BlueprintResultTimeline | undefined
392386
if (blueprint.blueprint.onTimelineGenerate) {
387+
const blueprintPersistentState = new PersistentPlayoutStateStore(
388+
playoutModel.playlist.previousPersistentState
389+
)
390+
393391
const span = context.startSpan('blueprint.onTimelineGenerate')
394392
const influxTrace = startTrace('blueprints:onTimelineGenerate')
395-
tlGenRes = await blueprint.blueprint.onTimelineGenerate(
393+
const tlGenRes = await blueprint.blueprint.onTimelineGenerate(
396394
blueprintContext,
397395
timelineObjs,
398-
clone(playoutModel.playlist.previousPersistentState),
396+
blueprintPersistentState,
399397
clone(currentPartInstance?.partInstance?.previousPartEndState),
400398
resolvedPieces.map(convertResolvedPieceInstanceToBlueprints)
401399
)
@@ -408,10 +406,13 @@ async function getTimelineRundown(
408406
objectType: TimelineObjType.RUNDOWN,
409407
})
410408
})
409+
410+
if (blueprintPersistentState.hasChanges) {
411+
playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll())
412+
}
411413
}
412414

413-
playoutModel.setOnTimelineGenerateResult(
414-
tlGenRes?.persistentState,
415+
playoutModel.setAbResolvingState(
415416
newAbSessionsResult.assignments,
416417
blueprintContext.abSessionsHelper.knownSessions
417418
)

0 commit comments

Comments
 (0)