Silence a free video once its sprite is destroyed (#420)
A sprite whose Video clock is free played its video on after it was destroyed, heard in a game, until the player was let go 2 to 4 s later. A driven one was already held and quiet after 100 ms. - The library holds and quiets a free player nothing asked for in HUSH_MS, as it did a driven one. That covers Destroy, a scene load, the end of a run and a sprite switched off. - Asked for again before it is let go, it plays on from where it was held, heard only in a run. A hidden page leaves it alone, as the sweep does. - A sprite only out of view keeps its free video playing and heard. Whether a video is heard should not hang on the camera. Before, it ran 2 to 4 s and was then let go. Now it plays on, which opens its player even where it was never in view. Tests: - Unit: video-library 1 new. A free player losing its wearer is held and quiet 200 ms later, stays so through a new run, plays on heard when asked again with the same element, and runs on on a hidden page. - e2e 66 on melektaus-atx: ALL PASSED, 36 checks, 66g-ii new. Heard 31 frames before Destroy, held and muted in every frame read after. - Counter-probe without hushing free players: the unit test and only 66g-ii fail, the player plays on heard (paused false, muted false). - Gate on melektaus-atx: 309 files, 4797 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
acd12326dc
commit
875c76026a
5 files changed
+166
-19
No files matched your search
@@ -258,6 +258,64 @@ describe('VideoLibrary driven players (#404)', () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('holds a free player quiet once no sprite wears it, and plays it on when one does (#420)', async () => {
|
||||
vi.useFakeTimers({ toFake: ['setInterval', 'clearInterval', 'performance'] });
|
||||
const page = { hidden: false };
|
||||
const events = new Map<string, () => void>();
|
||||
let frames: (() => void)[] = [];
|
||||
const element = {
|
||||
...fakeVideo(),
|
||||
play() {
|
||||
this.paused = false;
|
||||
return Promise.resolve();
|
||||
},
|
||||
pause() {
|
||||
this.paused = true;
|
||||
},
|
||||
addEventListener: (type: string, listener: () => void) => events.set(type, listener),
|
||||
requestVideoFrameCallback: (callback: () => void) => frames.push(callback),
|
||||
};
|
||||
vi.stubGlobal('document', {
|
||||
get hidden() {
|
||||
return page.hidden;
|
||||
},
|
||||
addEventListener: () => {},
|
||||
createElement: () => element,
|
||||
});
|
||||
const { soundLibrary } = await import('../../src/viewport/SoundLibrary');
|
||||
vi.spyOn(soundLibrary, 'mediaInput').mockReturnValue(null);
|
||||
const videos = await freshLibrary();
|
||||
const drawFor = (ms: number) => {
|
||||
for (let at = 0; at < ms; at += 1000 / 60) {
|
||||
videos.get(KEY);
|
||||
vi.advanceTimersByTime(1000 / 60);
|
||||
}
|
||||
};
|
||||
videos.get(KEY);
|
||||
events.get('loadeddata')!();
|
||||
[frames] = [[], ...frames.map((frame) => frame())];
|
||||
videos.startRun();
|
||||
drawFor(1000);
|
||||
const state = () => [element.paused, element.muted];
|
||||
expect(state()).toEqual([false, false]);
|
||||
// Its sprite is destroyed: held and quiet at once, not heard until it is let go 2-4 s later.
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(state()).toEqual([true, true]);
|
||||
// A run started meanwhile takes it back to its start, still quiet.
|
||||
videos.startRun();
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(state()).toEqual([true, true]);
|
||||
// Worn again before it is let go: it plays on, heard, the same video.
|
||||
videosMade = 0;
|
||||
drawFor(500);
|
||||
expect([...state(), videosMade]).toEqual([false, false, 0]);
|
||||
// A hidden page draws nothing, and asks for nothing: it plays on as before.
|
||||
page.hidden = true;
|
||||
vi.advanceTimersByTime(1000);
|
||||
expect(state()).toEqual([false, false]);
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('tells a view whether one of its driven players still waits for its first picture', async () => {
|
||||
const videos = await freshLibrary();
|
||||
videos.get(KEY);
|
||||
|
||||
Reference in new issue
Block a user