Keep a driven video ready while its sprite is off (#404)
A cut between two videos flashed white: the sprite switched on had no picture yet, because its player only opened then or had been dropped meanwhile. A driven video now waits muted at its time while its sprite is off, in the editor and in a run. - A disabled sprite with Video clock Driven asks for its player without drawing it. A Free video still opens when shown. - A run's draw list keeps disabled driven sprites, marked as off. Before, collectWorldItems dropped every disabled object, so the game view never held a player for them. - VideoLibrary.wear() counts as asking. The sweeper dropped a held player after 2 to 4 s and it was loading again at the cut. - The speed of the asked time is read over a window that grows to 500 ms. Over 100 ms one 1/60 s step more or less read as 17 % off, the playback rate jumped and the sound dropped out. - A stream feeds every packet it has loaded to the decoder at once and waits once. One round trip per 20 ms packet let the decoder fall behind on a busy main thread, which made e2e 34 flaky in CI. Tests: - Unit streaming, video-library, video-follow: green, 4 new - e2e 34 + 66 (atx): ALL PASSED, stream skipped 0, 66m new - e2e 66 (atx), two runs: ALL PASSED, 25 checks, 66n new - Gate (atx): CHECK EXIT 0, 297 files, 4557 tests - Counter-checks: without the draw list fix 66n finds no player, without the wear() fix and with the old speed reading the new unit tests turn red Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
774207208c
commit
43fd22a763
11 files changed
+202
-40
No files matched your search
@@ -383,6 +383,49 @@ export async function video(t) {
|
||||
);
|
||||
await showTab('scene');
|
||||
|
||||
// 66m. Switched off, a driven sprite keeps its player ready at its Video time, longer than a player
|
||||
// nobody asks for lives: switched on, the first frame shows 1.2 s blue, not its plain colour.
|
||||
// 4.5 s, as the sweeper looks only every 2 s and lets go of what is 2 s idle.
|
||||
const switchLate = (on) =>
|
||||
mutate(`
|
||||
const late = __gm.state.activeScene.objects.find((o) => o.id === '${LATE}');
|
||||
late.overrides = { ...late.overrides, videoTime: 1.2, enabled: ${on} };`);
|
||||
await switchLate(false);
|
||||
await sleep(4500);
|
||||
const readied = (await json('__gm.videos()')).find((v) => v.key.includes(LATE));
|
||||
await switchLate(true);
|
||||
await t.evaluate('__gm.afterFrames(1)');
|
||||
const firstShown = await colorAt(await json(`__gm.objectRect('${LATE}')`));
|
||||
check(
|
||||
'a driven sprite switched off keeps its video ready and shows its picture the frame it is switched on',
|
||||
readied?.ready === true &&
|
||||
readied.paused &&
|
||||
readied.muted &&
|
||||
Math.abs(readied.time - 1.2) < 0.05 &&
|
||||
firstShown === COLORS.blue,
|
||||
JSON.stringify({ readied, firstShown }),
|
||||
);
|
||||
|
||||
// 66n. The same in a run: the world used to leave a switched-off object out of what the Game tab
|
||||
// draws, so a cut to it loaded the video only then and showed white meanwhile. Nor did wearing
|
||||
// the player count as asking for it: let go after 2 to 4 s, it was opened again.
|
||||
await switchLate(false);
|
||||
const sceneKeys = new Set((await json('__gm.videos()')).map((v) => v.key));
|
||||
await play();
|
||||
await sleep(4500);
|
||||
const inRun = (await json('__gm.videos()')).filter((v) => v.key.includes(LATE) && !sceneKeys.has(v.key));
|
||||
await stop();
|
||||
await switchLate(true);
|
||||
check(
|
||||
'in a run, a driven sprite switched off keeps its video ready too',
|
||||
inRun.length === 1 &&
|
||||
inRun[0].ready &&
|
||||
inRun[0].paused &&
|
||||
inRun[0].muted &&
|
||||
Math.abs(inRun[0].time - 1.2) < 0.05,
|
||||
JSON.stringify(inRun),
|
||||
);
|
||||
|
||||
await mutate(`
|
||||
const p = __gm.state.project;
|
||||
const gone = ['${OBJECT}', '${EARLY}', '${LATE}'];
|
||||
|
||||
Reference in new issue
Block a user