mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Take a hidden shape off the globe whole, and keep every drawn shape
Answers the review of bdbbc3d7 and the IC8 pass after it.
A shape hidden from Draw's list was only set to alpha 0, so the line's
flowing stroke, which keeps its own colour, stayed painted. Now:
- the world renderer's sync() sets every entity of a hidden mark to
show = false, and FlowMaterialProperty follows the mark's alpha;
- the screen renderer does not project a hidden callout, so it is not drawn
and cannot push a visible label aside;
- hiding acts at once, even before a mark's first frame, and with every
mark hidden the annotations render hold is released after one last frame;
- fly_route skips a hidden route.
Hand-drawn shapes are never merged as duplicates: every one is drawn on
purpose and unnamed until its row names it, so a second pin dropped near
the first was dropped, or replaced the first when its colour differed. A
restyle the renderer cannot draw now also syncs the renderer.
Tests cover each: renderer show/hide and flow alpha, the screen skip, the
render hold and its last frame, a show with no fade-in, hidden routes, two
nearby pins, and the restyle rollback.
This commit is contained in:
1 parent
4ebb287d36
commit
38eb98b8f8
8 files changed
+288
-6
No files matched your search
@@ -987,3 +987,108 @@ test('a drawn line that rounds up to the next unit is labelled in it, not as 100
|
||||
assert.deepEqual(labels, ['990 m', '1.0 km', '9.9 km', '10 km']);
|
||||
engine.destroy();
|
||||
});
|
||||
|
||||
test('hand-drawn marks: two unnamed pins close together are two pins, whatever their colours', async (t) => {
|
||||
installAnimationFrameStubs(t);
|
||||
_resetRenderGovernorForTest();
|
||||
t.after(() => _resetRenderGovernorForTest());
|
||||
const { renderer } = fakeRenderer();
|
||||
const engine = createAnnotationEngine({ viewer: {}, renderer });
|
||||
const pin = (lon, color) => ({ type: 'pin', manual: true, latitude: 30.27, longitude: lon, label: '', color });
|
||||
await engine.annotate([pin(-97.74, 'primary')], { persist: true });
|
||||
await engine.annotate([pin(-97.7402, 'primary')], { persist: true });
|
||||
await engine.annotate([pin(-97.7404, 'red')], { persist: true });
|
||||
assert.deepEqual(
|
||||
engine.list().map(({ color }) => color),
|
||||
['primary', 'primary', 'red'],
|
||||
'no drawn pin is dropped or replaced by the next',
|
||||
);
|
||||
});
|
||||
|
||||
test('hand-drawn marks: hiding a mark before its first frame takes it off at once', async (t) => {
|
||||
installAnimationFrameStubs(t);
|
||||
_resetRenderGovernorForTest();
|
||||
t.after(() => _resetRenderGovernorForTest());
|
||||
let syncs = 0;
|
||||
const renderer = { add() {}, update() {}, remove() {}, sync() { syncs += 1; }, destroy() {} };
|
||||
const engine = createAnnotationEngine({ viewer: {}, renderer });
|
||||
await engine.annotate([{ type: 'pin', manual: true, latitude: 1, longitude: 1 }], { persist: true });
|
||||
const [mark] = engine.list();
|
||||
const before = syncs;
|
||||
engine.setHidden(mark.id, true);
|
||||
assert.ok(syncs > before, 'the renderer hears about it now');
|
||||
assert.ok(
|
||||
!getRenderGovernorDiagnostics().holds.includes('annotations'),
|
||||
'and the render hold goes with the last visible mark',
|
||||
);
|
||||
});
|
||||
|
||||
test('hand-drawn marks: with every mark hidden the scene idles, and showing one wakes it', async (t) => {
|
||||
installAnimationFrameStubs(t);
|
||||
_resetRenderGovernorForTest();
|
||||
t.after(() => _resetRenderGovernorForTest());
|
||||
let renders = 0;
|
||||
installRenderGovernor({ scene: { requestRenderMode: true, requestRender: () => (renders += 1) } });
|
||||
const { renderer } = fakeRenderer();
|
||||
const engine = createAnnotationEngine({ viewer: {}, renderer });
|
||||
await engine.annotate([
|
||||
{ type: 'pin', manual: true, latitude: 1, longitude: 1 },
|
||||
{ type: 'pin', manual: true, latitude: 2, longitude: 2 },
|
||||
], { persist: true });
|
||||
const [first, second] = engine.list();
|
||||
const held = () => getRenderGovernorDiagnostics().holds.includes('annotations');
|
||||
assert.ok(held(), 'visible marks keep the scene drawing');
|
||||
engine.setHidden(first.id, true);
|
||||
assert.ok(held(), 'one visible mark is enough');
|
||||
const before = renders;
|
||||
engine.setHidden(second.id, true);
|
||||
assert.equal(held(), false, 'every mark hidden: the scene idles');
|
||||
assert.ok(renders > before, 'after one last frame that takes them off');
|
||||
engine.setHidden(second.id, false);
|
||||
assert.ok(held(), 'showing one wakes it again');
|
||||
});
|
||||
|
||||
test('hand-drawn marks: a restyle the renderer cannot draw takes the mark off and says so', async (t) => {
|
||||
installAnimationFrameStubs(t);
|
||||
_resetRenderGovernorForTest();
|
||||
t.after(() => _resetRenderGovernorForTest());
|
||||
const { renderer, failAddOnce } = throwingRendererHarness();
|
||||
let syncs = 0;
|
||||
renderer.sync = () => (syncs += 1);
|
||||
const engine = createAnnotationEngine({ viewer: {}, renderer });
|
||||
await engine.annotate([{ type: 'pin', manual: true, latitude: 1, longitude: 1 }], { persist: true });
|
||||
const [mark] = engine.list();
|
||||
let changes = 0;
|
||||
engine.onChange(() => (changes += 1));
|
||||
const before = syncs;
|
||||
failAddOnce();
|
||||
assert.throws(() => engine.restyle(mark.id, { color: 'red' }), /WebGL context lost/);
|
||||
assert.equal(engine.list().length, 0, 'no ghost row is left behind');
|
||||
assert.equal(changes, 1, 'the list hears about it');
|
||||
assert.ok(syncs > before, 'and the renderer is told');
|
||||
});
|
||||
|
||||
test('hand-drawn marks: a mark shown again right after it was drawn appears at once, not fading in', async (t) => {
|
||||
_resetRenderGovernorForTest();
|
||||
t.after(() => _resetRenderGovernorForTest());
|
||||
const queued = [];
|
||||
const raf = globalThis.requestAnimationFrame;
|
||||
const caf = globalThis.cancelAnimationFrame;
|
||||
globalThis.requestAnimationFrame = (callback) => queued.push(callback);
|
||||
globalThis.cancelAnimationFrame = () => {};
|
||||
t.after(() => {
|
||||
globalThis.requestAnimationFrame = raf;
|
||||
globalThis.cancelAnimationFrame = caf;
|
||||
});
|
||||
const tick = () => queued.splice(0).forEach((callback) => callback());
|
||||
const { renderer } = fakeRenderer();
|
||||
const engine = createAnnotationEngine({ viewer: {}, renderer });
|
||||
await engine.annotate([{ type: 'pin', manual: true, latitude: 1, longitude: 1 }], { persist: true });
|
||||
const [mark] = engine.list();
|
||||
engine.setHidden(mark.id, true);
|
||||
tick();
|
||||
assert.equal(mark.alpha, 0);
|
||||
engine.setHidden(mark.id, false);
|
||||
tick();
|
||||
assert.equal(mark.alpha, 1, 'no fade-in after a hide');
|
||||
});
|
||||
Reference in new issue
Block a user