fix: make soundtrack loading terminal
This commit is contained in:
@@ -387,7 +387,9 @@ export function createSoundtrackEngine(
|
||||
mainSource = main;
|
||||
mainSchedule = schedule;
|
||||
attachMainEnded(main);
|
||||
for (const source of introSourceNodes) {
|
||||
const committedIntroSources = introSourceNodes;
|
||||
introSourceNodes = [];
|
||||
for (const source of committedIntroSources) {
|
||||
source.stopAt(transitionTime + EXIT_CROSSFADE_SECONDS);
|
||||
}
|
||||
loadedIntroBuffer = null;
|
||||
@@ -456,22 +458,24 @@ export function createSoundtrackEngine(
|
||||
void mainPromise.catch(() => undefined);
|
||||
|
||||
if (activatedFromStart) {
|
||||
loadedIntroBuffer = await dependencies.loadBuffer(context, sources.intro, signal);
|
||||
const [introBuffer, mainBuffer] = await Promise.all([
|
||||
dependencies.loadBuffer(context, sources.intro, signal),
|
||||
mainPromise,
|
||||
]);
|
||||
if (closed || signal.aborted) throw abortError();
|
||||
loadedIntroBuffer = introBuffer;
|
||||
if (latestChapter.atStart) {
|
||||
transportStarted = true;
|
||||
startIntro(loadedIntroBuffer, context.currentTime + SOURCE_LEAD_SECONDS);
|
||||
return;
|
||||
}
|
||||
transportStarted = true;
|
||||
startDirectMain(mainBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
const mainBuffer = await mainPromise;
|
||||
if (closed || signal.aborted) throw abortError();
|
||||
if (activatedFromStart && latestChapter.atStart && loadedIntroBuffer !== null) {
|
||||
transportStarted = true;
|
||||
startIntro(loadedIntroBuffer, context.currentTime + SOURCE_LEAD_SECONDS);
|
||||
return;
|
||||
}
|
||||
transportStarted = true;
|
||||
startDirectMain(mainBuffer);
|
||||
};
|
||||
@@ -514,6 +518,16 @@ export function createSoundtrackEngine(
|
||||
mixer.dispose();
|
||||
for (const source of [...ownedSources]) source.cancel();
|
||||
ownedSources.clear();
|
||||
pendingIntroExit = null;
|
||||
introSourceNodes = [];
|
||||
introProgramGain = null;
|
||||
mainSource = null;
|
||||
driveLiftSource = null;
|
||||
afterglowSource = null;
|
||||
mainSchedule = null;
|
||||
mainBufferPromise = null;
|
||||
loadPromise = null;
|
||||
exitLoadRequest = null;
|
||||
context.removeEventListener('statechange', onStateChange);
|
||||
stateListeners.clear();
|
||||
outputGain.disconnect();
|
||||
|
||||
@@ -306,14 +306,18 @@ describe('soundtrack engine', () => {
|
||||
expect(test.mixer.setDriveEnergy).toHaveBeenLastCalledWith(sample);
|
||||
});
|
||||
|
||||
it('keeps dominant intro and direct-main load failures terminal', async () => {
|
||||
it('keeps dominant intro and main load failures terminal on every activation path', async () => {
|
||||
const intro = createEngineHarness(initialState, { rejectIntro: true });
|
||||
await expect(intro.graph.resume()).rejects.toThrow('/intro.opus unavailable');
|
||||
const main = createEngineHarness({
|
||||
const startMain = createEngineHarness(initialState, { rejectMain: true });
|
||||
await expect(startMain.graph.resume()).rejects.toThrow('/main.opus unavailable');
|
||||
expect(startMain.sourcesFor('/intro.opus')).toHaveLength(0);
|
||||
|
||||
const directMain = createEngineHarness({
|
||||
chapter: resolveChapterIntent('profile'),
|
||||
drive: { energy: 0, source: 'idle' },
|
||||
}, { rejectMain: true });
|
||||
await expect(main.graph.resume()).rejects.toThrow('/main.opus unavailable');
|
||||
await expect(directMain.graph.resume()).rejects.toThrow('/main.opus unavailable');
|
||||
});
|
||||
|
||||
it('stops and disconnects each owned source exactly once when closed twice', async () => {
|
||||
|
||||
Reference in New Issue
Block a user