mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 18:34:02 +00:00
184 lines
7.0 KiB
JavaScript
184 lines
7.0 KiB
JavaScript
import * as Cesium from 'cesium';
|
|
import { ISS_OVERLAY_SOURCE_ID } from './policy.js';
|
|
|
|
export function createLifecycle({
|
|
state: layerState,
|
|
services,
|
|
parts,
|
|
source,
|
|
}) {
|
|
const { clearFocusTarget } = services.focus;
|
|
const { holdContinuousRender, releaseContinuousRender } = services.render;
|
|
const { registerPickOwner, unregisterPickOwner } = services.picking;
|
|
|
|
const methods = {
|
|
// Catalog data refresh; propagation remains preRender-owned.
|
|
|
|
async init(viewer) {
|
|
parts.catalog._abortActiveUpdates();
|
|
clearFocusTarget('satellites');
|
|
layerState._viewer = viewer;
|
|
layerState._catalog = new Map();
|
|
layerState._points = new Map();
|
|
layerState._detectionObjects = new Map();
|
|
layerState._orbitPaths = new Map();
|
|
layerState._count = 0;
|
|
layerState._lastUpdate = null;
|
|
layerState._coreStale = false;
|
|
layerState._denseStale = false;
|
|
layerState._trackedNorad = null;
|
|
parts.tracking._cancelPendingTrackingRestore();
|
|
layerState._trackedEntity = null;
|
|
layerState._trackedFrameNumber = -1;
|
|
layerState._trackedFrameGeo = null;
|
|
layerState._trackedFrameNowForTest = null;
|
|
layerState._lastFocusUpdate = 0;
|
|
layerState._activeFocusCount = 0;
|
|
layerState._enabled = false;
|
|
layerState._overlayHost.clearSource(ISS_OVERLAY_SOURCE_ID);
|
|
layerState._overlayHost.setVisible(ISS_OVERLAY_SOURCE_ID, false);
|
|
// Dense extras rebuild via update() when _params.catalog === 'dense'
|
|
// (the catalog-mode preference itself is sticky across init/destroy).
|
|
layerState._denseIds = [];
|
|
layerState._denseCursor = 0;
|
|
layerState._denseLoadPromise = null;
|
|
layerState._denseLoadToken++;
|
|
layerState._denseStatus = 'idle';
|
|
layerState._denseError = null;
|
|
layerState._catalogRevision++;
|
|
|
|
// Point primitives for satellite dots
|
|
layerState._pointCollection = new Cesium.PointPrimitiveCollection();
|
|
viewer.scene.primitives.add(layerState._pointCollection);
|
|
|
|
parts.interaction._installClickHandler(viewer);
|
|
|
|
// Pre-render listener for real-time position updates
|
|
// (fleet propagation + tracked per-frame dot + orbit ring GMST rotation)
|
|
layerState._preRenderListener = viewer.scene.preRender.addEventListener(
|
|
parts.rendering._preRenderTick,
|
|
);
|
|
|
|
console.log('[Data:Satellites] Initialized');
|
|
},
|
|
|
|
enable(viewer) {
|
|
layerState._enabled = true;
|
|
holdContinuousRender('satellites'); // per-frame animator (perf wave 2)
|
|
if (layerState._pointCollection)
|
|
layerState._pointCollection.show =
|
|
parts.controls.satelliteVisualsVisible(
|
|
layerState._enabled,
|
|
layerState._params.showPoints,
|
|
);
|
|
// Orbit ring primitives + persistent ISS host label — show them
|
|
for (const path of layerState._orbitPaths.values())
|
|
path.primitive.show = parts.controls.satelliteVisualsVisible(
|
|
layerState._enabled,
|
|
layerState._params.showOrbits,
|
|
);
|
|
parts.labels._syncIssOverlay();
|
|
// Re-attach input handlers and preRender propagation
|
|
parts.interaction._installClickHandler(viewer);
|
|
// Pick-ownership (H2): satellite dot ids are numeric NORAD catalog numbers;
|
|
// the registry hands predicates String()-coerced ids, so match via Number().
|
|
registerPickOwner('satellites', (pickedId) => {
|
|
const norad = Number(pickedId);
|
|
return Number.isFinite(norad) && layerState._points.has(norad);
|
|
});
|
|
if (!layerState._preRenderListener && viewer) {
|
|
layerState._preRenderListener = viewer.scene.preRender.addEventListener(
|
|
parts.rendering._preRenderTick,
|
|
);
|
|
}
|
|
parts.tracking._applyPendingTrackingRestore();
|
|
},
|
|
|
|
disable(viewer) {
|
|
parts.catalog._abortActiveUpdates();
|
|
parts.tracking._cancelPendingTrackingRestore();
|
|
layerState._enabled = false;
|
|
releaseContinuousRender('satellites');
|
|
if (layerState._pointCollection) layerState._pointCollection.show = false;
|
|
for (const path of layerState._orbitPaths.values())
|
|
path.primitive.show = false;
|
|
parts.tracking._clearTracking();
|
|
parts.labels._syncIssOverlay();
|
|
// Remove click handler + keydown listener + preRender propagation while disabled
|
|
if (layerState._clickHandler) {
|
|
layerState._clickHandler.destroy();
|
|
layerState._clickHandler = null;
|
|
}
|
|
if (layerState._trackedEntityChangedRemove) {
|
|
layerState._trackedEntityChangedRemove();
|
|
layerState._trackedEntityChangedRemove = null;
|
|
}
|
|
document.removeEventListener('keydown', parts.interaction._onKeyDown);
|
|
unregisterPickOwner('satellites');
|
|
if (layerState._preRenderListener) {
|
|
layerState._preRenderListener();
|
|
layerState._preRenderListener = null;
|
|
}
|
|
},
|
|
|
|
destroy(viewer) {
|
|
parts.catalog._abortActiveUpdates();
|
|
releaseContinuousRender('satellites'); // direct-destroy path (perf wave 2 fix)
|
|
layerState._enabled = false;
|
|
parts.tracking._clearTracking();
|
|
parts.tracking._cancelPendingTrackingRestore();
|
|
if (layerState._clickHandler) {
|
|
layerState._clickHandler.destroy();
|
|
layerState._clickHandler = null;
|
|
}
|
|
if (layerState._trackedEntityChangedRemove) {
|
|
layerState._trackedEntityChangedRemove();
|
|
layerState._trackedEntityChangedRemove = null;
|
|
}
|
|
document.removeEventListener('keydown', parts.interaction._onKeyDown);
|
|
unregisterPickOwner('satellites');
|
|
if (layerState._preRenderListener) {
|
|
layerState._preRenderListener();
|
|
layerState._preRenderListener = null;
|
|
}
|
|
layerState._overlayHost.clearSource(ISS_OVERLAY_SOURCE_ID);
|
|
layerState._overlayHost.setVisible(ISS_OVERLAY_SOURCE_ID, false);
|
|
if (layerState._pointCollection) {
|
|
viewer.scene.primitives.remove(layerState._pointCollection);
|
|
layerState._pointCollection = null;
|
|
}
|
|
// Orbit ring primitives are removed (and destroyed) here
|
|
for (const path of layerState._orbitPaths.values()) {
|
|
viewer.scene.primitives.remove(path.primitive);
|
|
}
|
|
layerState._points.clear();
|
|
layerState._detectionObjects.clear();
|
|
layerState._orbitPaths.clear();
|
|
layerState._catalog.clear();
|
|
layerState._denseIds = [];
|
|
layerState._denseCursor = 0;
|
|
layerState._denseLoadToken++;
|
|
layerState._denseStatus = 'idle';
|
|
layerState._denseError = null;
|
|
layerState._catalogRevision++;
|
|
layerState._rowControlsListener = null;
|
|
layerState._count = 0;
|
|
layerState._lastUpdate = null;
|
|
layerState._coreStale = false;
|
|
layerState._denseStale = false;
|
|
layerState._lastError = null;
|
|
layerState._lastFocusUpdate = 0;
|
|
layerState._activeFocusCount = 0;
|
|
layerState._trackingRefreshEpoch += 1;
|
|
layerState._lastTrackingRefreshOutcome = {
|
|
epoch: layerState._trackingRefreshEpoch,
|
|
status: 'destroyed',
|
|
failedGroups: [],
|
|
};
|
|
layerState._viewer = null;
|
|
},
|
|
};
|
|
|
|
return { methods };
|
|
}
|