diff --git a/packages/blueprints-integration/src/context/onTakeContext.ts b/packages/blueprints-integration/src/context/onTakeContext.ts index 3918bdd7ee..461f64bfa1 100644 --- a/packages/blueprints-integration/src/context/onTakeContext.ts +++ b/packages/blueprints-integration/src/context/onTakeContext.ts @@ -1,4 +1,4 @@ -import { IEventContext, IShowStyleUserContext, Time } from '../index.js' +import { IBlueprintPart, IBlueprintPiece, IEventContext, IShowStyleUserContext, Time } from '../index.js' import { IPartAndPieceActionContext } from './partsAndPieceActionContext.js' import { IExecuteTSRActionsContext } from './executeTsrActionContext.js' @@ -18,4 +18,6 @@ export interface IOnTakeContext * but the next part will not be taken. */ abortTake(): void + /** Insert a queued part to follow the taken part */ + queuePartAfterTake(part: IBlueprintPart, pieces: IBlueprintPiece[]): void } diff --git a/packages/job-worker/src/blueprints/context/OnTakeContext.ts b/packages/job-worker/src/blueprints/context/OnTakeContext.ts index 578f038c33..144f6d3543 100644 --- a/packages/job-worker/src/blueprints/context/OnTakeContext.ts +++ b/packages/job-worker/src/blueprints/context/OnTakeContext.ts @@ -28,6 +28,7 @@ import { BlueprintQuickLookInfo } from '@sofie-automation/blueprints-integration export class OnTakeContext extends ShowStyleUserContext implements IOnTakeContext, IEventContext { public isTakeAborted: boolean + public partToQueue: { rawPart: IBlueprintPart; rawPieces: IBlueprintPiece[] } | undefined public get quickLoopInfo(): BlueprintQuickLookInfo | null { return this.partAndPieceInstanceService.quickLoopInfo @@ -153,6 +154,10 @@ export class OnTakeContext extends ShowStyleUserContext implements IOnTakeContex return executePeripheralDeviceAction(this._context, deviceId, null, actionId, payload) } + queuePartAfterTake(rawPart: IBlueprintPart, rawPieces: IBlueprintPiece[]): void { + this.partToQueue = { rawPart, rawPieces } + } + getCurrentTime(): number { return getCurrentTime() } diff --git a/packages/job-worker/src/playout/take.ts b/packages/job-worker/src/playout/take.ts index 67b8f51742..a4fdd34096 100644 --- a/packages/job-worker/src/playout/take.ts +++ b/packages/job-worker/src/playout/take.ts @@ -198,7 +198,13 @@ export async function performTakeToNextedPart( const showStyle = await pShowStyle const blueprint = await context.getShowStyleBlueprint(showStyle._id) - const { isTakeAborted } = await executeOnTakeCallback(context, playoutModel, showStyle, blueprint, currentRundown) + const { isTakeAborted, queuePart } = await executeOnTakeCallback( + context, + playoutModel, + showStyle, + blueprint, + currentRundown + ) if (isTakeAborted) { await updateTimeline(context, playoutModel) @@ -264,8 +270,12 @@ export async function performTakeToNextedPart( resetPreviousSegmentIfLooping(context, playoutModel) } - // Once everything is synced, we can choose the next part - await setNextPart(context, playoutModel, nextPart, false) + if (queuePart) { + await queuePart() + } else { + // Once everything is synced, we can choose the next part + await setNextPart(context, playoutModel, nextPart, false) + } // If the Hold is PENDING, make it active if (playoutModel.playlist.holdState === RundownHoldState.PENDING) { @@ -289,10 +299,11 @@ async function executeOnTakeCallback( showStyle: ReadonlyObjectDeep, blueprint: ReadonlyObjectDeep, currentRundown: PlayoutRundownModel -): Promise<{ isTakeAborted: boolean }> { +): Promise<{ isTakeAborted: boolean; queuePart: (() => Promise) | undefined }> { const NOTIFICATION_CATEGORY = 'onTake' let isTakeAborted = false + let queuePart: (() => Promise) | undefined = undefined if (blueprint.blueprint.onTake) { const rundownId = currentRundown.rundown._id const partInstanceId = playoutModel.playlist.nextPartInfo?.partInstanceId @@ -300,6 +311,7 @@ async function executeOnTakeCallback( // Clear any existing notifications for this partInstance. This will clear any from the previous take playoutModel.clearAllNotifications(NOTIFICATION_CATEGORY) + const actionService = new PartAndPieceInstanceActionService(context, playoutModel, showStyle, currentRundown) const watchedPackagesHelper = WatchedPackagesHelper.empty(context) const onSetAsNextContext = new OnTakeContext( @@ -313,7 +325,7 @@ async function executeOnTakeCallback( playoutModel, showStyle, watchedPackagesHelper, - new PartAndPieceInstanceActionService(context, playoutModel, showStyle, currentRundown) + actionService ) try { const blueprintPersistentState = new PersistentPlayoutStateStore( @@ -323,6 +335,12 @@ async function executeOnTakeCallback( await blueprint.blueprint.onTake(onSetAsNextContext, blueprintPersistentState) await applyOnTakeSideEffects(context, playoutModel, onSetAsNextContext) isTakeAborted = onSetAsNextContext.isTakeAborted + if (onSetAsNextContext.partToQueue) { + const partToQueue = onSetAsNextContext.partToQueue + queuePart = async () => { + await actionService.queuePart(partToQueue.rawPart, partToQueue.rawPieces) + } + } if (blueprintPersistentState.hasChanges) { playoutModel.setBlueprintPersistentState(blueprintPersistentState.getAll()) @@ -354,7 +372,7 @@ async function executeOnTakeCallback( }) } } - return { isTakeAborted } + return { isTakeAborted, queuePart } } async function applyOnTakeSideEffects(context: JobContext, playoutModel: PlayoutModel, onTakeContext: OnTakeContext) {