mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(awareness): ignore canvas input while the cockpit owns the camera
The cockpit turns Cesium's camera controls off and moves the camera on its own, so a click, drag or wheel on the canvas moved nothing yet still counted as the user handling the map: the cockpit's next move woke a nine-second pulse burst. Input now counts only while the camera controls take it, and a gesture still pending when another owner takes the camera is dropped.
This commit is contained in:
1 parent
fe3d17df02
commit
56a7cacbec
4 files changed
+109
-3
No files matched your search
@@ -574,6 +574,99 @@ test('a camera move seen by the lifecycle wakes resting pulses; a parked camera
|
||||
assert.equal(state.lastCameraInputMs < Date.now() - inputWakeMs, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* The lifecycle's camera-input listeners over `ring`, with a camera the test
|
||||
* moves by longitude (`pan`) and a camera controller whose inputs it can
|
||||
* switch off, as the cockpit view does. Pulses start resting.
|
||||
*/
|
||||
function inputLifecycle(t, ring) {
|
||||
const { state, rendering } = ring;
|
||||
const loop = frameLoop(t, ring, { date: true });
|
||||
state.enabled = true;
|
||||
state.viewer.canvas = new EventTarget();
|
||||
state.viewer.scene.screenSpaceCameraController = { enableInputs: true };
|
||||
state.viewer.camera = {
|
||||
positionWC: Cesium.Cartesian3.fromDegrees(3, 20, 800_000),
|
||||
heading: 0,
|
||||
pitch: -1,
|
||||
roll: 0,
|
||||
};
|
||||
const lifecycle = createLifecycle({
|
||||
state,
|
||||
services: {
|
||||
render: { holdContinuousRender() {}, releaseContinuousRender() {} },
|
||||
},
|
||||
parts: {
|
||||
rendering,
|
||||
model: {
|
||||
awarenessRefreshDecision: () => ({ moving: false, refresh: false }),
|
||||
awarenessNeedsContinuousRender: () => false,
|
||||
},
|
||||
},
|
||||
});
|
||||
lifecycle.attachRuntimeListeners();
|
||||
t.after(() => lifecycle.detachRuntimeListeners());
|
||||
rendering.renderVisual(flight(3));
|
||||
loop.advance(AWARENESS_RANGE_PULSE.activeMs + 500);
|
||||
let lon = 3;
|
||||
return {
|
||||
loop,
|
||||
lifecycle,
|
||||
controller: state.viewer.scene.screenSpaceCameraController,
|
||||
dispatch: (type, init = {}) =>
|
||||
state.viewer.canvas.dispatchEvent(Object.assign(new Event(type), init)),
|
||||
pan(stepDeg = 0.1) {
|
||||
lon += stepDeg;
|
||||
state.viewer.camera.positionWC = Cesium.Cartesian3.fromDegrees(
|
||||
lon,
|
||||
20,
|
||||
800_000,
|
||||
);
|
||||
loop.draw();
|
||||
},
|
||||
/** Whether the pulses drew frames during the next `ms`. */
|
||||
pulsing(ms = AWARENESS_RANGE_PULSE.activeMs) {
|
||||
const before = ring.pulseFrames();
|
||||
loop.advance(ms);
|
||||
return ring.pulseFrames() > before;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('input the camera controller ignores, as in the cockpit, does not wake the pulses', (t) => {
|
||||
const ring = ringRendering(t);
|
||||
const { activeMs } = AWARENESS_RANGE_PULSE;
|
||||
const { controller, dispatch, pan, pulsing, loop } = inputLifecycle(t, ring);
|
||||
// The cockpit takes the camera: clicks, drags and wheels on the canvas
|
||||
// move nothing, while the cockpit itself moves the camera every frame.
|
||||
controller.enableInputs = false;
|
||||
for (const [type, init] of [
|
||||
['pointerdown', {}],
|
||||
['pointermove', { buttons: 1 }],
|
||||
['wheel', {}],
|
||||
['touchstart', {}],
|
||||
]) {
|
||||
dispatch(type, init);
|
||||
pan();
|
||||
assert.equal(pulsing(), false, `${type} in the cockpit`);
|
||||
}
|
||||
// A gesture that began just before the cockpit took the camera is
|
||||
// dropped too, rather than waking the pulses on the cockpit's first move.
|
||||
controller.enableInputs = true;
|
||||
loop.advance(activeMs);
|
||||
dispatch('pointerdown');
|
||||
controller.enableInputs = false;
|
||||
pan();
|
||||
assert.equal(pulsing(), false, 'a gesture cut off by the cockpit');
|
||||
controller.enableInputs = true;
|
||||
pan();
|
||||
assert.equal(pulsing(), false, 'and stays dropped once it hands back');
|
||||
// Back in the user's hands, a drag wakes them again.
|
||||
dispatch('pointerdown');
|
||||
pan();
|
||||
assert.equal(pulsing(), true, 'a drag after the cockpit');
|
||||
});
|
||||
|
||||
test('disabling the layer tears the pulses down completely', (t) => {
|
||||
const ring = ringRendering(t);
|
||||
const { state, scene, rendering, motion, pulseFrames } = ring;
|
||||
|
||||
Reference in new issue
Block a user