Dispose the Navara bloom and sharpen passes when their effect is deleted

EffectComposer.removePass does not dispose a pass. One withPassDisposal mixin now does it for the bloom, sharpen, styles and overlay effects.
This commit is contained in:
German Khokhlov committed 2026-11-03 23:30:10 +04:00
1 parent b49f9dddf0
commit cbe1d841ea
6 files changed
+67 -27

No files matched your search

+37 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { withFrameUpdates } from './frameDescriptor.js';
import { withFrameUpdates, withPassDisposal } from './frameDescriptor.js';
test('deleting a descriptor unsubscribes only that renderer from the warm view', () => {
const frames = new Set();
@@ -41,3 +41,39 @@ test('deleting a descriptor unsubscribes only that renderer from the warm view',
b.onDestroy();
assert.equal(frames.size, 0);
});
test('a deleted effect disposes the pass the composer no longer holds', () => {
const events = [];
const pass = { dispose: () => events.push('dispose') };
class Base {
_instance = { rawPass: pass };
get raw() {
return this._instance;
}
onDestroy() {
events.push('remove');
this._instance = undefined;
}
}
const effect = new (withPassDisposal(Base))();
effect.onDestroy();
assert.deepEqual(events, ['remove', 'dispose']);
// A pass that was never created: nothing to dispose.
const empty = new (withPassDisposal(
class {
onDestroy() {}
},
))();
assert.doesNotThrow(() => empty.onDestroy());
// The pass is disposed even when Navara's removal throws.
class Failing extends Base {
onDestroy() {
throw Error('removal failed');
}
}
events.length = 0;
assert.throws(() => new (withPassDisposal(Failing))().onDestroy(), /removal/);
assert.deepEqual(events, ['dispose']);
});