fix(maps): defer 3D attachment until the selection is current

This commit is contained in:
Sameh Khamis committed 2026-09-13 18:59:29 -07:00
1 parent e59282dc9c
commit 06c73bca98
2 files changed
+63 -16

No files matched your search

+12 -16
View File
@@ -147,25 +147,16 @@ export class MapSourceController {
if (!tileset) {
if (!source.createTileset)
throw new Error(`Missing 3D source: ${source.descriptor.id}`);
tileset = await this._cached(
this._tilesets,
source.descriptor.id,
async () => {
const value = await source.createTileset({
signal: this._abort.signal,
});
if (this._destroyed) {
this._dispose(value);
return value;
}
value.show = false;
this.viewer.scene.primitives.add(value);
this._ownedTilesets.add(value);
return value;
},
tileset = await this._cached(this._tilesets, source.descriptor.id, () =>
source.createTileset({ signal: this._abort.signal }),
);
}
if (gen !== this._switchGen) return;
if (!source.tileset && !this._ownedTilesets.has(tileset)) {
tileset.show = false;
this.viewer.scene.primitives.add(tileset);
this._ownedTilesets.add(tileset);
}
this._removeImageryLayer();
this._credits.show(source.credit || null);
this._showTileset(tileset);
@@ -325,6 +316,11 @@ export class MapSourceController {
this.viewer.scene.primitives.remove(tileset);
this._dispose(tileset);
}
for (const promise of this._tilesets.values())
void Promise.resolve(promise).then(
(value) => this._dispose(value),
() => {},
);
this._imageryProviders.clear();
this._terrainProviders.clear();
this._tilesets.clear();
+51
View File
@@ -298,3 +298,54 @@ test('invalid source graphs fail before constructing or caching a provider', ()
assert.throws(() => fixture({ sources: [a, a] }), /unique/);
assert.throws(() => fixture({ sources: [a] }), /Unknown map fallback/);
});
for (const reactivate of [false, true]) {
test(`a superseded 3D load stays outside the scene and is released (reactivate: ${reactivate})`, async () => {
let resolve,
destroyed = 0,
reads = 0;
const tileset = {
show: true,
isDestroyed: () => destroyed > 0,
destroy() {
destroyed++;
},
};
const supplied = { show: true };
const env = fixture({
defaultId: 'slow',
sources: [
{
descriptor: { id: 'slow' },
createTileset: () => {
reads++;
return new Promise((done) => {
resolve = done;
});
},
},
{ descriptor: { id: 'supplied' }, tileset: supplied },
],
});
const loading = env.controller.setStack('slow');
await settle();
await env.controller.setStack('supplied');
resolve(tileset);
await loading;
assert.equal(env.primitives.length, 0);
assert.equal(supplied.show, true);
assert.equal(env.controller.getActiveId(), 'supplied');
if (reactivate) {
await env.controller.setStack('slow');
await env.controller.setStack('slow');
assert.deepEqual(env.primitives, [tileset]);
assert.equal(reads, 1);
assert.equal(tileset.show, true);
assert.equal(supplied.show, false);
}
env.controller.destroy();
await settle();
assert.equal(env.primitives.length, 0);
assert.equal(destroyed, 1);
});
}