Show a recoverable notice when the globe stops drawing

Cesium stops its render loop after a render error and offers only a
panel that dismisses itself, and a lost WebGL context never draws again,
so the globe froze or went black while the controls kept responding.

The scene chrome now shows an alert dialog with the error. Retry restarts
the render loop and keeps the notice until a frame renders without an
error; after a lost context it reloads the page, whose address keeps the
view. Reset view opens the app root without the restored hash or share
path. An inline conversation panel never reloads its host page. The
application viewer turns off Cesium's own panel; other callers keep it.
This commit is contained in:
German Khokhlov committed 2026-11-05 13:03:14 +04:00
1 parent 7d8b80db0a
commit fbec1488ac
23 files changed
+658 -16

No files matched your search

+18 -1
View File
@@ -7,7 +7,9 @@ import { markRaw, shallowRef } from 'vue';
* road network chip, CctvControls the camera grid chip; the toast shows
* what any owner's createToast() (src/ui/toast.js) publishes, and the title
* bar the FPS readout createFrameRateMonitor() publishes. Each label keeps its
* last text while hidden, so the next change flaps from what was shown.
* last text while hidden, so the next change flaps from what was shown. The
* render failure notice is what installRenderFailureNotice()
* (src/ui/renderFailure.js) publishes while the globe cannot draw.
*/
export const useStatusStore = defineStore('gev-status', () => {
/**
@@ -32,6 +34,14 @@ export const useStatusStore = defineStore('gev-status', () => {
*/
const fps = shallowRef(null);
/**
* The globe's render failure, `{reason, detail, shown, retry, reset}`; null
* while the globe draws. `reason` is 'render-error' or 'context-lost',
* `shown` changes each time the notice appears, and `retry` and `reset` are
* null where that action is not offered.
*/
const renderFailure = shallowRef(null);
/** @param {?object} next A fresh presentation of the loading status. */
function publishLoading(next) {
loading.value = next && markRaw(next);
@@ -57,6 +67,11 @@ export const useStatusStore = defineStore('gev-status', () => {
fps.value = next && markRaw(next);
}
/** @param {?object} next A fresh presentation of the render failure. */
function publishRenderFailure(next) {
renderFailure.value = next && markRaw(next);
}
return {
fps,
publishFps,
@@ -68,5 +83,7 @@ export const useStatusStore = defineStore('gev-status', () => {
publishTraffic,
cctv,
publishCctv,
renderFailure,
publishRenderFailure,
};
});