mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
Stop a Bhote Koshi attachment that resumes after its scene was released
This commit is contained in:
1 parent
2853938df7
commit
baabff6acf
2 files changed
+77
-5
No files matched your search
@@ -1177,7 +1177,7 @@ export function createBhoteKoshiEventLayer({
|
|||||||
return _event;
|
return _event;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createImagery(event) {
|
async function createImagery(event, current = () => true) {
|
||||||
const rectangle = Cesium.Rectangle.fromDegrees(
|
const rectangle = Cesium.Rectangle.fromDegrees(
|
||||||
event.imagery.rectangle.west,
|
event.imagery.rectangle.west,
|
||||||
event.imagery.rectangle.south,
|
event.imagery.rectangle.south,
|
||||||
@@ -1194,13 +1194,13 @@ export function createBhoteKoshiEventLayer({
|
|||||||
credit: 'Vantor WorldView Open Data · CC BY-NC 4.0',
|
credit: 'Vantor WorldView Open Data · CC BY-NC 4.0',
|
||||||
}),
|
}),
|
||||||
]));
|
]));
|
||||||
if (!_enabled) return;
|
if (!_enabled || !current()) return;
|
||||||
if (_native) {
|
if (_native) {
|
||||||
await _native.loadImages(event.imagery.rectangle, [
|
await _native.loadImages(event.imagery.rectangle, [
|
||||||
beforeProvider,
|
beforeProvider,
|
||||||
afterProvider,
|
afterProvider,
|
||||||
]);
|
]);
|
||||||
setSplit(_split);
|
if (current()) setSplit(_split);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_imageryLayerCollection = _viewer.imageryLayers;
|
_imageryLayerCollection = _viewer.imageryLayers;
|
||||||
@@ -3516,7 +3516,15 @@ export function createBhoteKoshiEventLayer({
|
|||||||
_imageryLayerCollection = null;
|
_imageryLayerCollection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function attachRenderer(viewer, { engine = null } = {}) {
|
// Each attachment and release advances this. An attachment that resumes
|
||||||
|
// after a release, or after its scene signal aborted, stops right there;
|
||||||
|
// the release that follows it owns whatever it had already created.
|
||||||
|
let _attachGeneration = 0;
|
||||||
|
|
||||||
|
async function attachRenderer(viewer, { engine = null, signal = null } = {}) {
|
||||||
|
const generation = ++_attachGeneration;
|
||||||
|
const current = () =>
|
||||||
|
generation === _attachGeneration && signal?.aborted !== true;
|
||||||
_viewer = viewer;
|
_viewer = viewer;
|
||||||
_engine = engine;
|
_engine = engine;
|
||||||
if (!_viewer && _engine) _native = createNativeRenderer(engine);
|
if (!_viewer && _engine) _native = createNativeRenderer(engine);
|
||||||
@@ -3532,16 +3540,20 @@ export function createBhoteKoshiEventLayer({
|
|||||||
: 'esri',
|
: 'esri',
|
||||||
});
|
});
|
||||||
await _comparisonLease.ready;
|
await _comparisonLease.ready;
|
||||||
|
if (!current()) return;
|
||||||
}
|
}
|
||||||
await createImagery(_event);
|
await createImagery(_event, current);
|
||||||
|
if (!current()) return;
|
||||||
if (_floodDataSource) {
|
if (_floodDataSource) {
|
||||||
if (_native) _nativeFlood = _native.draw(_floodDataSource);
|
if (_native) _nativeFlood = _native.draw(_floodDataSource);
|
||||||
else await _viewer.dataSources.add(_floodDataSource);
|
else await _viewer.dataSources.add(_floodDataSource);
|
||||||
|
if (!current()) return;
|
||||||
}
|
}
|
||||||
registerDynamicCredit(engine ?? viewer, BHOTE_KOSHI_CREDIT);
|
registerDynamicCredit(engine ?? viewer, BHOTE_KOSHI_CREDIT);
|
||||||
_scenePathPositionCache.clear();
|
_scenePathPositionCache.clear();
|
||||||
_lastCinematicProgress = null;
|
_lastCinematicProgress = null;
|
||||||
await syncTerrainComparison();
|
await syncTerrainComparison();
|
||||||
|
if (!current()) return;
|
||||||
createSplitControl(_event);
|
createSplitControl(_event);
|
||||||
syncPresentationMode();
|
syncPresentationMode();
|
||||||
attachCameraInputRelease();
|
attachCameraInputRelease();
|
||||||
@@ -3551,6 +3563,7 @@ export function createBhoteKoshiEventLayer({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function detachRenderer() {
|
async function detachRenderer() {
|
||||||
|
++_attachGeneration;
|
||||||
detachCameraInputRelease();
|
detachCameraInputRelease();
|
||||||
detachEvidenceCardActivation();
|
detachEvidenceCardActivation();
|
||||||
_splitControl?.destroy();
|
_splitControl?.destroy();
|
||||||
|
|||||||
@@ -2992,3 +2992,62 @@ test('Bhote Koshi corridor remains ordered downstream and inside the imagery rec
|
|||||||
priorChainage = point.chainageM;
|
priorChainage = point.chainageM;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const stop of ['detach', 'scene-abort']) {
|
||||||
|
test(`Bhote Koshi attach resumed after a ${stop} leaves the next scene untouched`, async () => {
|
||||||
|
const event = JSON.parse(await readFile(eventUrl, 'utf8'));
|
||||||
|
const originalDocument = globalThis.document;
|
||||||
|
const originalWindow = globalThis.window;
|
||||||
|
installEventDom();
|
||||||
|
globalThis.window = { setTimeout: () => 1, clearTimeout() {} };
|
||||||
|
const first = eventViewer();
|
||||||
|
const second = eventViewer();
|
||||||
|
const layer = createBhoteKoshiEventLayer({
|
||||||
|
eventLoader: async () => event,
|
||||||
|
imageryProviderFactory: async (url) => ({ url }),
|
||||||
|
embeddedMediaFactory: () => ({ show() {}, hide() {}, pause() {}, destroy() {} }),
|
||||||
|
overlayHost: { setEntries() {}, setVisible() {}, clearSource() {} },
|
||||||
|
renderHost: { request() {}, hold() {}, release() {} },
|
||||||
|
});
|
||||||
|
const stack = (initial, gate = null) => {
|
||||||
|
let active = initial;
|
||||||
|
let generation = 1;
|
||||||
|
return {
|
||||||
|
getActiveId: () => active,
|
||||||
|
getSwitchGeneration: () => generation,
|
||||||
|
async setStack(id) {
|
||||||
|
await gate;
|
||||||
|
active = id;
|
||||||
|
generation += 1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
layer.attachMapStackController(stack('esri-imagery'));
|
||||||
|
const manager = new LayerLifecycle(first);
|
||||||
|
manager.register(layer);
|
||||||
|
try {
|
||||||
|
assert.equal(await manager.setEnabled(layer.id, true, { origin: 'local-restore' }), true);
|
||||||
|
await layer.detachRenderer();
|
||||||
|
|
||||||
|
// The incoming map has to switch first: the attachment waits on it.
|
||||||
|
let openGate;
|
||||||
|
const gate = new Promise((resolve) => { openGate = resolve; });
|
||||||
|
layer.attachMapStackController(stack('photoreal', gate));
|
||||||
|
const scene = new AbortController();
|
||||||
|
const attaching = layer.attachRenderer(second, { signal: scene.signal });
|
||||||
|
let detaching = null;
|
||||||
|
if (stop === 'detach') detaching = layer.detachRenderer();
|
||||||
|
else scene.abort();
|
||||||
|
openGate();
|
||||||
|
await attaching;
|
||||||
|
await detaching;
|
||||||
|
assert.deepEqual(second._test.imagery, []);
|
||||||
|
assert.deepEqual(second._test.dataSources, []);
|
||||||
|
if (stop === 'scene-abort') await layer.detachRenderer();
|
||||||
|
} finally {
|
||||||
|
await manager.destroyLayer(layer.id);
|
||||||
|
globalThis.document = originalDocument;
|
||||||
|
globalThis.window = originalWindow;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in new issue
Block a user