Skip to content

Commit b127ff1

Browse files
committed
wip
1 parent 7d0140b commit b127ff1

File tree

10 files changed

+254
-88
lines changed

10 files changed

+254
-88
lines changed

packages/corelib/src/playout/__tests__/processAndPrune.test.ts

Lines changed: 139 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { literal } from '../../lib'
66
import { protectString } from '../../protectedString'
77
import {
88
createPartCurrentTimes,
9+
PartCurrentTimes,
910
PieceInstanceWithTimings,
1011
processAndPrunePieceInstanceTimings,
1112
resolvePrunedPieceInstance,
@@ -45,7 +46,11 @@ describe('processAndPrunePieceInstanceTimings', () => {
4546
})
4647
}
4748

48-
function runAndTidyResult(pieceInstances: PieceInstance[], nowInPart: number, includeVirtual?: boolean) {
49+
function runAndTidyResult(
50+
pieceInstances: PieceInstance[],
51+
nowInPart: number | PartCurrentTimes,
52+
includeVirtual?: boolean
53+
) {
4954
const resolvedInstances = processAndPrunePieceInstanceTimings(
5055
{
5156
one: {
@@ -62,7 +67,7 @@ describe('processAndPrunePieceInstanceTimings', () => {
6267
},
6368
},
6469
pieceInstances,
65-
createPartCurrentTimes(nowInPart, 0), // nocommit - this is a hack to avoid changing tests
70+
typeof nowInPart === 'number' ? createPartCurrentTimes(nowInPart, 0) : nowInPart, // nocommit - this is a hack to avoid changing tests
6671
undefined,
6772
includeVirtual
6873
)
@@ -469,6 +474,100 @@ describe('processAndPrunePieceInstanceTimings', () => {
469474
},
470475
])
471476
})
477+
478+
describe('absolute timed (rundown owned) pieces', () => {
479+
test('simple collision', () => {
480+
const now = 9000
481+
const partStart = 8000
482+
483+
const pieceInstances = [
484+
createPieceInstance('one', { start: 0 }, 'one', PieceLifespan.OutOnRundownChange),
485+
createPieceInstance(
486+
'two',
487+
{ start: now + 2000, isAbsolute: true },
488+
'one',
489+
PieceLifespan.OutOnRundownChange
490+
),
491+
createPieceInstance('three', { start: 6000 }, 'one', PieceLifespan.OutOnRundownChange),
492+
]
493+
494+
const resolvedInstances = runAndTidyResult(pieceInstances, createPartCurrentTimes(now, partStart))
495+
expect(resolvedInstances).toEqual([
496+
{
497+
_id: 'one',
498+
priority: 5,
499+
start: 0,
500+
end: 3000,
501+
},
502+
{
503+
_id: 'two',
504+
priority: 5,
505+
start: partStart + 3000,
506+
end: partStart + 6000,
507+
},
508+
{
509+
_id: 'three',
510+
priority: 5,
511+
start: 6000,
512+
end: undefined,
513+
},
514+
])
515+
})
516+
517+
test('collision with same start time', () => {
518+
const now = 9000
519+
const partStart = 8000
520+
521+
const pieceInstances = [
522+
createPieceInstance('one', { start: 0 }, 'one', PieceLifespan.OutOnRundownChange),
523+
createPieceInstance(
524+
'two',
525+
{ start: partStart + 2000, isAbsolute: true },
526+
'one',
527+
PieceLifespan.OutOnRundownChange
528+
),
529+
createPieceInstance('three', { start: 2000 }, 'one', PieceLifespan.OutOnRundownChange),
530+
]
531+
532+
const resolvedInstances = runAndTidyResult(pieceInstances, createPartCurrentTimes(now, partStart))
533+
expect(resolvedInstances).toEqual([
534+
{
535+
_id: 'one',
536+
priority: 5,
537+
start: 0,
538+
end: 2000,
539+
},
540+
{
541+
_id: 'two',
542+
priority: 5,
543+
start: partStart + 2000,
544+
end: undefined,
545+
},
546+
])
547+
548+
{
549+
// check stability
550+
pieceInstances[1].piece.enable = { start: 2000 }
551+
pieceInstances[2].piece.enable = { start: partStart + 2000, isAbsolute: true }
552+
553+
const resolvedInstances = runAndTidyResult(pieceInstances, createPartCurrentTimes(now, partStart))
554+
expect(resolvedInstances).toEqual([
555+
{
556+
_id: 'one',
557+
priority: 5,
558+
start: 0,
559+
end: 2000,
560+
},
561+
{
562+
_id: 'three',
563+
priority: 5,
564+
start: partStart + 2000,
565+
end: undefined,
566+
},
567+
])
568+
}
569+
})
570+
})
472571
})
473572

474573
describe('resolvePrunedPieceInstances', () => {
@@ -504,10 +603,10 @@ describe('resolvePrunedPieceInstances', () => {
504603
}
505604

506605
test('numeric start, no duration', async () => {
507-
const nowInPart = 123
606+
const partTimes = createPartCurrentTimes(123, 0)
508607
const piece = createPieceInstance({ start: 2000 })
509608

510-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
609+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
511610
instance: clone(piece),
512611
timelinePriority: piece.priority,
513612
resolvedStart: 2000,
@@ -516,10 +615,10 @@ describe('resolvePrunedPieceInstances', () => {
516615
})
517616

518617
test('numeric start, with planned duration', async () => {
519-
const nowInPart = 123
618+
const partTimes = createPartCurrentTimes(123, 0)
520619
const piece = createPieceInstance({ start: 2000, duration: 3400 })
521620

522-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
621+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
523622
instance: clone(piece),
524623
timelinePriority: piece.priority,
525624
resolvedStart: 2000,
@@ -528,127 +627,127 @@ describe('resolvePrunedPieceInstances', () => {
528627
})
529628

530629
test('now start, no duration', async () => {
531-
const nowInPart = 123
630+
const partTimes = createPartCurrentTimes(123, 0)
532631
const piece = createPieceInstance({ start: 'now' })
533632

534-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
633+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
535634
instance: clone(piece),
536635
timelinePriority: piece.priority,
537-
resolvedStart: nowInPart,
636+
resolvedStart: partTimes.nowInPart,
538637
resolvedDuration: undefined,
539638
} satisfies ResolvedPieceInstance)
540639
})
541640

542641
test('now start, with planned duration', async () => {
543-
const nowInPart = 123
642+
const partTimes = createPartCurrentTimes(123, 0)
544643
const piece = createPieceInstance({ start: 'now', duration: 3400 })
545644

546-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
645+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
547646
instance: clone(piece),
548647
timelinePriority: piece.priority,
549-
resolvedStart: nowInPart,
648+
resolvedStart: partTimes.nowInPart,
550649
resolvedDuration: 3400,
551650
} satisfies ResolvedPieceInstance)
552651
})
553652

554653
test('now start, with end cap', async () => {
555-
const nowInPart = 123
654+
const partTimes = createPartCurrentTimes(123, 0)
556655
const piece = createPieceInstance({ start: 'now' }, 5000)
557656

558-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
657+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
559658
instance: clone(piece),
560659
timelinePriority: piece.priority,
561-
resolvedStart: nowInPart,
562-
resolvedDuration: 5000 - nowInPart,
660+
resolvedStart: partTimes.nowInPart,
661+
resolvedDuration: 5000 - partTimes.nowInPart,
563662
} satisfies ResolvedPieceInstance)
564663
})
565664

566665
test('now start, with end cap and longer planned duration', async () => {
567-
const nowInPart = 123
666+
const partTimes = createPartCurrentTimes(123, 0)
568667
const piece = createPieceInstance({ start: 'now', duration: 6000 }, 5000)
569668

570-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
669+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
571670
instance: clone(piece),
572671
timelinePriority: piece.priority,
573-
resolvedStart: nowInPart,
574-
resolvedDuration: 5000 - nowInPart,
672+
resolvedStart: partTimes.nowInPart,
673+
resolvedDuration: 5000 - partTimes.nowInPart,
575674
} satisfies ResolvedPieceInstance)
576675
})
577676

578677
test('now start, with end cap and shorter planned duration', async () => {
579-
const nowInPart = 123
678+
const partTimes = createPartCurrentTimes(123, 0)
580679
const piece = createPieceInstance({ start: 'now', duration: 3000 }, 5000)
581680

582-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
681+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
583682
instance: clone(piece),
584683
timelinePriority: piece.priority,
585-
resolvedStart: nowInPart,
684+
resolvedStart: partTimes.nowInPart,
586685
resolvedDuration: 3000,
587686
} satisfies ResolvedPieceInstance)
588687
})
589688

590689
test('now start, with userDuration.endRelativeToPart', async () => {
591-
const nowInPart = 123
690+
const partTimes = createPartCurrentTimes(123, 0)
592691
const piece = createPieceInstance({ start: 'now' }, undefined, {
593692
endRelativeToPart: 4000,
594693
})
595694

596-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
695+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
597696
instance: clone(piece),
598697
timelinePriority: piece.priority,
599-
resolvedStart: nowInPart,
600-
resolvedDuration: 4000 - nowInPart,
698+
resolvedStart: partTimes.nowInPart,
699+
resolvedDuration: 4000 - partTimes.nowInPart,
601700
} satisfies ResolvedPieceInstance)
602701
})
603702

604703
test('numeric start, with userDuration.endRelativeToNow', async () => {
605-
const nowInPart = 123
704+
const partTimes = createPartCurrentTimes(123, 0)
606705
const piece = createPieceInstance({ start: 500 }, undefined, {
607706
endRelativeToNow: 4000,
608707
})
609708

610-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
709+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
611710
instance: clone(piece),
612711
timelinePriority: piece.priority,
613712
resolvedStart: 500,
614-
resolvedDuration: 4000 - 500 + nowInPart,
713+
resolvedDuration: 4000 - 500 + partTimes.nowInPart,
615714
} satisfies ResolvedPieceInstance)
616715
})
617716

618717
test('now start, with userDuration.endRelativeToNow', async () => {
619-
const nowInPart = 123
718+
const partTimes = createPartCurrentTimes(123, 0)
620719
const piece = createPieceInstance({ start: 'now' }, undefined, {
621720
endRelativeToNow: 4000,
622721
})
623722

624-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
723+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
625724
instance: clone(piece),
626725
timelinePriority: piece.priority,
627-
resolvedStart: nowInPart,
726+
resolvedStart: partTimes.nowInPart,
628727
resolvedDuration: 4000,
629728
} satisfies ResolvedPieceInstance)
630729
})
631730

632731
test('now start, with end cap, planned duration and userDuration.endRelativeToPart', async () => {
633-
const nowInPart = 123
732+
const partTimes = createPartCurrentTimes(123, 0)
634733
const piece = createPieceInstance({ start: 'now', duration: 3000 }, 5000, { endRelativeToPart: 2800 })
635734

636-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
735+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
637736
instance: clone(piece),
638737
timelinePriority: piece.priority,
639-
resolvedStart: nowInPart,
640-
resolvedDuration: 2800 - nowInPart,
738+
resolvedStart: partTimes.nowInPart,
739+
resolvedDuration: 2800 - partTimes.nowInPart,
641740
} satisfies ResolvedPieceInstance)
642741
})
643742

644743
test('now start, with end cap, planned duration and userDuration.endRelativeToNow', async () => {
645-
const nowInPart = 123
744+
const partTimes = createPartCurrentTimes(123, 0)
646745
const piece = createPieceInstance({ start: 'now', duration: 3000 }, 5000, { endRelativeToNow: 2800 })
647746

648-
expect(resolvePrunedPieceInstance(nowInPart, clone(piece))).toStrictEqual({
747+
expect(resolvePrunedPieceInstance(partTimes, clone(piece))).toStrictEqual({
649748
instance: clone(piece),
650749
timelinePriority: piece.priority,
651-
resolvedStart: nowInPart,
750+
resolvedStart: partTimes.nowInPart,
652751
resolvedDuration: 2800,
653752
} satisfies ResolvedPieceInstance)
654753
})

packages/corelib/src/playout/infinites.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,16 @@ export function isCandidateMoreImportant(
536536
best: ReadonlyDeep<PieceInstance>,
537537
candidate: ReadonlyDeep<PieceInstance>
538538
): boolean | undefined {
539+
// If one is absolute timed, prefer that
540+
if (best.piece.enable.isAbsolute && !candidate.piece.enable.isAbsolute) {
541+
// Prefer the absolute best
542+
return false
543+
}
544+
if (!best.piece.enable.isAbsolute && candidate.piece.enable.isAbsolute) {
545+
// Prefer the absolute candidate
546+
return true
547+
}
548+
539549
// Prioritise the one from this part over previous part
540550
if (best.infinite?.fromPreviousPart && !candidate.infinite?.fromPreviousPart) {
541551
// Prefer the candidate as it is not from previous

0 commit comments

Comments
 (0)