Skip to content

feat: allow multiple objects on a layer to get lookahead from a single piece SOFIE-464#1776

Merged
Julusian merged 1 commit into
Sofie-Automation:mainfrom
bbc:feat/SOFIE-464-multiple-lookahead-objects-from-piece
Jun 29, 2026
Merged

feat: allow multiple objects on a layer to get lookahead from a single piece SOFIE-464#1776
Julusian merged 1 commit into
Sofie-Automation:mainfrom
bbc:feat/SOFIE-464-multiple-lookahead-objects-from-piece

Conversation

@Julusian

Copy link
Copy Markdown
Member

About the Contributor

This pull request is posted on behalf of the BBC

Type of Contribution

This is a: Bug fix / Feature

Current Behavior

A piece is only able to produce one lookahead object on any layer. This is a problem if the piece needs to claim 2 sessions from an AB pool.

New Behavior

This removes the limit of producing one lookahead object per layer per piece. This was an artificial limitation, and I do not remember why it was added.

In our testing this has been fine, but I am not 100% confident that this wont cause negative side effects of producing too many objects in other circumstances. A potential side effect of this could be some pieces claiming too many AB sessions, or other timeline oddities. Others should keep an eye out for any side effects from this change.

Testing

  • I have added one or more unit tests for this PR
  • I have updated the relevant unit tests
  • No unit test changes are needed for this PR

Affected areas

Time Frame

Other Information

Status

  • PR is ready to be reviewed.
  • The functionality has been tested by the author.
  • Relevant unit tests has been added / updated.
  • Relevant documentation (code comments, system documentation) has been added / updated.

@Julusian Julusian added the Contribution from BBC Contributions sponsored by BBC (bbc.co.uk) label Jun 16, 2026
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

PieceInstanceWithObjectMap.objectMap is changed to store arrays of TimelineObjectCoreExt per layer key. getObjectMapForPiece and findLookaheadObjectsForPart in findObjects.ts are updated to accumulate and iterate over those arrays. Instance matching switches from piece._id to getBestPieceInstanceId. Tests are added and updated accordingly.

Changes

Multi-object-per-layer lookahead

Layer / File(s) Summary
objectMap type and findObjects implementation
packages/job-worker/src/playout/lookahead/util.ts, packages/job-worker/src/playout/lookahead/findObjects.ts
PieceInstanceWithObjectMap.objectMap value type changes from a single TimelineObjectCoreExt to TimelineObjectCoreExt[]; getObjectMapForPiece appends objects into per-layer arrays; findLookaheadObjectsForPart iterates the full array per layer and uses getBestPieceInstanceId for piece-instance matching.
findObjects multi-object and transition-filtering tests
packages/job-worker/src/playout/lookahead/__tests__/findObjects.test.ts
Four new test cases: all same-layer objects from a Normal piece are returned; start=0 Normal objects are filtered when an InTransition piece is on the same layer; Normal objects are not filtered when the InTransition piece is on a different layer; combined InTransition and later-starting Normal multi-object pieces filter only start=0 Normal objects.
makeSimplePiece helper and updated lookaheadOffset tests
packages/job-worker/src/playout/lookahead/__tests__/lookaheadOffset/constants.ts, packages/job-worker/src/playout/lookahead/__tests__/lookaheadOffset/lookaheadOffset.test.ts
Adds makeSimplePiece test helper constructing a single-object Piece; updates test cases to use makeSimplePiece, pass protectString IDs to wrapPieceToInstance, and expand result-count and lookaheadOffset array assertions to reflect multi-object generation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

✨ enhancement

Suggested reviewers

  • nytamin
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main feature: allowing multiple lookahead objects from a single piece on the same layer.
Description check ✅ Passed The description thoroughly explains the current limitation, new behavior, testing approach, and potential concerns, directly relating to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/job-worker/src/playout/lookahead/findObjects.ts (1)

164-169: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Transition filtering is over-broad for multi-object pieces.

At Line 168, filtering uses piece.piece.enable.start === 0, so once a transition object exists on this layer, all objects from that piece are dropped—even objects that start later. This can incorrectly suppress non-overlapping lookahead objects from a multi-object piece.

Proposed fix (filter by object timing, not parent-piece timing)
 			if (
 				hasTransitionObj &&
-				obj.pieceInstanceId &&
 				piece.piece.pieceType === IBlueprintPieceType.Normal &&
-				piece.piece.enable.start === 0
+				!Array.isArray(obj.enable) &&
+				obj.enable.start === 0
 			) {
 				return
 			}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/job-worker/src/playout/lookahead/findObjects.ts` around lines 164 -
169, The transition object filtering at line 168 in the condition block is
overly broad because it checks piece.piece.enable.start === 0 (the parent
piece's start time) rather than the individual object's start time. This causes
all objects from that piece to be dropped if the piece enables at 0, even if
individual objects start later and don't actually overlap with the transition.
Replace the check of piece.piece.enable.start === 0 with a check of the
individual object's enable.start property (such as obj.enable.start) so that
only objects whose timing actually conflicts with the transition are filtered
out.
🧹 Nitpick comments (1)
packages/job-worker/src/playout/lookahead/__tests__/findObjects.test.ts (1)

1073-1415: ⚡ Quick win

Add one regression case for temporary-piece ID matching.

The implementation now matches by getBestPieceInstanceId (see findObjects.ts Line 160), but this new suite only exercises non-temporary pieces. Please add a case with isTemporary: true and no partInstanceId to verify objects still map to the correct piece and aren’t dropped.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/job-worker/src/playout/lookahead/__tests__/findObjects.test.ts`
around lines 1073 - 1415, Add a new test case within the 'single piece with
multiple objects on the same layer' describe block to verify that temporary
pieces are correctly handled during ID matching. Create a test that sets
`isTemporary: true` on a piece instance and omits or sets `partInstanceId` to
undefined/null, then call `findLookaheadObjectsForPart` and verify that all
objects from the temporary piece are correctly returned and mapped to the
correct piece using `getBestPieceInstanceId` logic. This ensures the new ID
matching implementation properly handles temporary pieces without dropping
objects.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/job-worker/src/playout/lookahead/findObjects.ts`:
- Around line 164-169: The transition object filtering at line 168 in the
condition block is overly broad because it checks piece.piece.enable.start === 0
(the parent piece's start time) rather than the individual object's start time.
This causes all objects from that piece to be dropped if the piece enables at 0,
even if individual objects start later and don't actually overlap with the
transition. Replace the check of piece.piece.enable.start === 0 with a check of
the individual object's enable.start property (such as obj.enable.start) so that
only objects whose timing actually conflicts with the transition are filtered
out.

---

Nitpick comments:
In `@packages/job-worker/src/playout/lookahead/__tests__/findObjects.test.ts`:
- Around line 1073-1415: Add a new test case within the 'single piece with
multiple objects on the same layer' describe block to verify that temporary
pieces are correctly handled during ID matching. Create a test that sets
`isTemporary: true` on a piece instance and omits or sets `partInstanceId` to
undefined/null, then call `findLookaheadObjectsForPart` and verify that all
objects from the temporary piece are correctly returned and mapped to the
correct piece using `getBestPieceInstanceId` logic. This ensures the new ID
matching implementation properly handles temporary pieces without dropping
objects.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3001734b-823f-46e3-aa16-732709667c3e

📥 Commits

Reviewing files that changed from the base of the PR and between c965434 and 8e84fb3.

📒 Files selected for processing (5)
  • packages/job-worker/src/playout/lookahead/__tests__/findObjects.test.ts
  • packages/job-worker/src/playout/lookahead/__tests__/lookaheadOffset/constants.ts
  • packages/job-worker/src/playout/lookahead/__tests__/lookaheadOffset/lookaheadOffset.test.ts
  • packages/job-worker/src/playout/lookahead/findObjects.ts
  • packages/job-worker/src/playout/lookahead/util.ts

@Julusian Julusian merged commit 1912a4d into Sofie-Automation:main Jun 29, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Contribution from BBC Contributions sponsored by BBC (bbc.co.uk)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants