mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
Give each scene its own render governor, owner holds and recent idle requests. Make the Cesium render backend own its request mode directly, so the governor drives engine.render on both engines without a dependency back from Cesium. Route layer requests through their attached engine and capture the attachment's governor for camera motions, orbit, annotations and shell controls. Release retained-layer holds before clearing the outgoing engine, and destroy the governor after scene consumers have detached. Preserve Cesium's owner-keyed holds, pre-install buffering, last-release settling frame and one-shot requests during continuous rendering. Navara keeps the same render policy. There is no intended visible change on either engine. Simultaneous scenes no longer share holds, and an old captured service cannot release a replacement attachment's hold. Cover both rules on fake and headless Cesium engines, including an old orbit ending after reattachment. Viewer-reference lines fall from 910 to 891, Navara-kind checks from 2 to 1, and engine-name lines from 33 to 32. All other coupling counts stay unchanged. Checked in the browser, keyless: qa-perf passes on both engines with the same idle, active and release counts as before (24 checks on Cesium, 22 on Navara).
86 lines
2.6 KiB
JavaScript
86 lines
2.6 KiB
JavaScript
// Cesium owns its render mode and scene effects. Scene services drive this API.
|
|
|
|
import { CONTACT_SONAR_INITIAL, mergeContactSonar } from '../contract.js';
|
|
import { createCesiumPostStages } from './postStages.js';
|
|
import { createCesiumSonar } from './sonar.js';
|
|
|
|
export const RENDER_OWNER = 'globe-engine';
|
|
|
|
/**
|
|
* @param {Cesium.Viewer} viewer
|
|
* @param {{ requestRender?: (reason: string) => void,
|
|
* createStage?: (options: object) => object,
|
|
* createSonar?: typeof createCesiumSonar }} [options] `requestRender`
|
|
* defaults to the scene itself;
|
|
* `createStage` (postStages.js) and `createSonar` are test seams.
|
|
* @returns {{ render: import('../contract.js').GlobeRender,
|
|
* sonarDiagnostics: () => object, destroy: () => void }}
|
|
*/
|
|
export function createCesiumRender(
|
|
viewer,
|
|
{
|
|
requestRender = () => viewer.scene.requestRender?.(),
|
|
createStage,
|
|
createSonar = createCesiumSonar,
|
|
} = {},
|
|
) {
|
|
viewer.scene.maximumRenderTimeChange = Infinity;
|
|
const effects = createCesiumPostStages(viewer, {
|
|
requestRender,
|
|
...(createStage ? { createStage } : {}),
|
|
});
|
|
const sonar = createSonar(viewer);
|
|
let contactSonar = { ...CONTACT_SONAR_INITIAL };
|
|
// Whether Cesium is drawing a frame: a sonar change outside one asks for
|
|
// a frame, one inside it (the app's, every frame) draws in it.
|
|
let drawing = false;
|
|
let removeFrameWatch = null;
|
|
const watchFrames = () => {
|
|
const { scene } = viewer;
|
|
if (removeFrameWatch || !scene.preUpdate?.addEventListener) return;
|
|
const removers = [
|
|
scene.preUpdate.addEventListener(() => {
|
|
drawing = true;
|
|
}),
|
|
scene.postRender.addEventListener(() => {
|
|
drawing = false;
|
|
}),
|
|
];
|
|
removeFrameWatch = () => {
|
|
for (const remove of removers) remove();
|
|
};
|
|
};
|
|
const render = {
|
|
request(reason = RENDER_OWNER) {
|
|
requestRender(reason);
|
|
},
|
|
setContinuous(enabled) {
|
|
viewer.scene.requestRenderMode = !enabled;
|
|
},
|
|
isContinuous: () => viewer.scene.requestRenderMode === false,
|
|
...effects.render,
|
|
setContactSonar(options) {
|
|
const next = mergeContactSonar(contactSonar, options);
|
|
const changed = Object.keys(next).some(
|
|
(key) => next[key] !== contactSonar[key],
|
|
);
|
|
contactSonar = next;
|
|
if (!changed) return;
|
|
watchFrames();
|
|
sonar.set({ ...next });
|
|
if (!drawing) requestRender('cyber-sonar');
|
|
},
|
|
contactSonar: () => ({ ...contactSonar }),
|
|
};
|
|
return {
|
|
render,
|
|
sonarDiagnostics: () => sonar.diagnostics(),
|
|
destroy() {
|
|
render.setContinuous(false);
|
|
removeFrameWatch?.();
|
|
sonar.destroy();
|
|
effects.destroy();
|
|
},
|
|
};
|
|
}
|