Files
gods-eye-view/src/cctvFocusPolicy.js
T

82 lines
3.0 KiB
JavaScript

/**
* Activates the nearest CCTV record on layer enable and flies only when no
* aircraft tracker or cockpit camera owns the view.
* @param {Object} options Layer-enable focus inputs.
* @param {*} options.trackedEntity Current Cesium tracked entity, if any.
* @param {boolean} options.cockpitActive Whether cockpit mode owns the camera.
* @param {() => (string|null)} options.activate Nearest-camera activation.
* @param {(cameraId: string) => *} options.fly Optional camera flight.
* @returns {*} Activated camera ID for a held view, or the flight result.
*/
export function runCctvLayerEnableFocus({
trackedEntity = null,
cockpitActive = false,
activate,
fly,
} = {}) {
const cameraId = activate?.();
if (!cameraId) return false;
if (trackedEntity || cockpitActive) return cameraId;
return fly?.(cameraId);
}
/**
* Merges camera ownership sampled on both sides of the awaited layer-enable
* chain. Either observation suppresses the optional CCTV focus flight.
* @param {Object} [before={}] Ownership immediately before the await.
* @param {Object} [after={}] Ownership immediately after the await.
* @returns {{ trackedEntity: *, cockpitActive: boolean }} Conservative ownership.
*/
export function mergeCctvEnableOwnership(before = {}, after = {}) {
return {
trackedEntity: before.trackedEntity || after.trackedEntity || null,
cockpitActive: !!(before.cockpitActive || after.cockpitActive),
};
}
/**
* Runs the awaited CCTV layer transition while preserving camera ownership
* observed on either side for the optional enable-focus policy.
*
* @param {Object} options Transition dependencies.
* @param {boolean} options.target Requested enabled state.
* @param {(target: boolean) => Promise<*>} options.setEnabled Layer transition.
* @param {() => Object} options.readOwnership Current tracked/cockpit state.
* @param {() => boolean} options.shouldFocus Post-transition focus predicate.
* @param {() => (string|null)} options.activate Nearest-camera activation.
* @param {(cameraId: string) => *} options.fly Optional camera flight.
* @param {Function} [options.debug] Diagnostic sink.
* @returns {Promise<*>} Focus-policy result, or null when no focus was requested.
*/
export async function runCctvLayerEnableTransition({
target,
setEnabled,
readOwnership,
shouldFocus,
activate,
fly,
debug = console.debug,
}) {
const ownershipBefore = readOwnership?.() || {};
if (target === true) {
debug?.('[UI:CCTV] ownership before setEnabled await', {
trackedId: ownershipBefore.trackedEntity?.id ?? null,
cockpitActive: !!ownershipBefore.cockpitActive,
});
}
await setEnabled?.(target);
const ownershipAfter = readOwnership?.() || {};
if (target === true) {
debug?.('[UI:CCTV] ownership after setEnabled await', {
trackedId: ownershipAfter.trackedEntity?.id ?? null,
cockpitActive: !!ownershipAfter.cockpitActive,
});
}
if (!target || !shouldFocus?.()) return null;
return runCctvLayerEnableFocus({
...mergeCctvEnableOwnership(ownershipBefore, ownershipAfter),
activate,
fly,
});
}