mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-08 04:14:02 +00:00
Keep a settled flight in reach of a later failed lookup
A new voice fly-to now records the last flight that moved as the one it replaced, landed or not; only a still-flying one passes on its manual-input count. A slow lookup cancelled by a direct flight that landed, followed by a lookup that found nothing, used to drop the queued motion, and a cancelled direct flight in the same place let it fall back to an older landing.
This commit is contained in:
1 parent
b683b8a64b
commit
4c9b27dc20
2 files changed
+72
-9
No files matched your search
+13
-9
@@ -1144,11 +1144,14 @@ export function createGevActionRunner({
|
||||
runOptions,
|
||||
);
|
||||
}
|
||||
// Chained fly-tos: a grab during the earlier one counts. The flight
|
||||
// replaced is the last one that moved, past lookups that found nothing.
|
||||
// Chained fly-tos: a grab during an earlier one still flying counts.
|
||||
// The flight replaced is the last one that moved, past lookups that
|
||||
// found nothing.
|
||||
const prior = voiceFlightTarget(voiceFlight);
|
||||
const replaced = prior && !prior.done ? prior : null;
|
||||
const flight = trackVoiceFlight(replaced?.inputCount, replaced);
|
||||
const flight = trackVoiceFlight(
|
||||
prior && !prior.done ? prior.inputCount : undefined,
|
||||
prior,
|
||||
);
|
||||
voiceFlight = flight;
|
||||
const flown = flyToRequestedLocation(viewer, args, {
|
||||
onFlightEnd: flight.settle,
|
||||
@@ -2961,10 +2964,10 @@ let voiceFlightCount = 0;
|
||||
|
||||
/**
|
||||
* A voice flight's end: 'arrived', 'cancelled' or 'failed', settled once.
|
||||
* `replaced` is the last flight that moved, if still pending when this one
|
||||
* began (past lookups that found nothing). It is kept only
|
||||
* while this one may turn out to have moved nothing (a lookup that found no
|
||||
* place), so a queued motion can look past it.
|
||||
* `replaced` is the last flight that moved when this one began (past lookups
|
||||
* that found nothing), landed or not. It is kept only while this one may turn
|
||||
* out to have moved nothing (a lookup that found no place), so a queued
|
||||
* motion can look past it to that flight and its outcome.
|
||||
*/
|
||||
function trackVoiceFlight(
|
||||
inputCount = manualCameraInputCount(),
|
||||
@@ -2996,7 +2999,8 @@ function trackVoiceFlight(
|
||||
* actually started. A lookup that found nothing moved nothing, so look past
|
||||
* it to the flight it replaced, but never to one older than `start` (a flight
|
||||
* from an earlier reply). Null when every later lookup found nothing. With
|
||||
* no `start`, the latest flight that started, however old.
|
||||
* no `start`, the latest flight that started, back through lookups that
|
||||
* found nothing.
|
||||
*/
|
||||
function voiceFlightTarget(latest, start = null) {
|
||||
let flight = latest;
|
||||
|
||||
@@ -791,6 +791,65 @@ test('two lookups that found nothing in a row still leave the motion waiting for
|
||||
assert.equal((await moved).ok, true);
|
||||
});
|
||||
|
||||
// A flight that already settled is still what a later failed lookup replaced.
|
||||
test('a motion acts at a landed flight that a later failed lookup replaced', async (t) => {
|
||||
t.after(() => interruptCameraMotion('test-cleanup'));
|
||||
const { viewer, styleManager, flights } = tiltAfterFlightHarness();
|
||||
const searches = [];
|
||||
const runner = createGevActionRunner({
|
||||
viewer,
|
||||
styleManager,
|
||||
dataManager: { layers: new Map(), getAll: () => [] },
|
||||
searchNavigation: (_viewer, query, options) => new Promise((resolve) => {
|
||||
searches.push({ query, options, resolve });
|
||||
}),
|
||||
});
|
||||
const flyA = runner('fly_to_location', { query: 'Slow A' });
|
||||
const moved = runner('move_camera', { motion: 'orbit' });
|
||||
assert.equal((await runner('fly_to_location', { locationId: 'austin' })).ok, true);
|
||||
flights[0].complete();
|
||||
const flyC = runner('fly_to_location', { query: 'Nowhere C' });
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
// B's start made A's lookup stale; C then finds nothing.
|
||||
searches[0].resolve({ cancelled: true });
|
||||
searches[1].resolve(null);
|
||||
assert.equal((await flyA).cancelled, true);
|
||||
assert.equal((await flyC).ok, false);
|
||||
const result = await moved;
|
||||
assert.equal(result.ok, true, result.error);
|
||||
});
|
||||
|
||||
test('a motion refuses when the flight a later failed lookup replaced was cancelled', async () => {
|
||||
const { viewer, styleManager, flights } = tiltAfterFlightHarness();
|
||||
const searches = [];
|
||||
const runner = createGevActionRunner({
|
||||
viewer,
|
||||
styleManager,
|
||||
dataManager: { layers: new Map(), getAll: () => [] },
|
||||
searchNavigation: (_viewer, query, options) => new Promise((resolve) => {
|
||||
searches.push({ query, options, resolve });
|
||||
}),
|
||||
});
|
||||
assert.equal((await runner('fly_to_location', { locationId: 'austin' })).ok, true);
|
||||
const moved = runner('move_camera', { motion: 'orbit' });
|
||||
const flyA = runner('fly_to_location', { query: 'Slow A' });
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
// The motion sees Austin land, then follows A's lookup.
|
||||
flights[0].complete();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
assert.equal((await runner('fly_to_location', { locationId: 'austin' })).ok, true);
|
||||
flights[1].cancel();
|
||||
const flyC = runner('fly_to_location', { query: 'Nowhere C' });
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
searches[0].resolve({ cancelled: true });
|
||||
searches[1].resolve(null);
|
||||
assert.equal((await flyA).cancelled, true);
|
||||
assert.equal((await flyC).ok, false);
|
||||
const result = await moved;
|
||||
assert.equal(result.ok, false);
|
||||
assert.match(result.error, /did not arrive/);
|
||||
});
|
||||
|
||||
test('a stale motion does not follow a newer reply\'s fly-to', async () => {
|
||||
const { viewer, styleManager, flights } = tiltAfterFlightHarness();
|
||||
const runner = createGevActionRunner({
|
||||
|
||||
Reference in new issue
Block a user