mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-08 04:14:02 +00:00
Prune queued-card rows whose pooled item paints another entry
A pooled paint item reused by another card keeps a fresh frame stamp, so rows for cards that stopped painting survived every prune and the index grew for the whole session. The prune now also drops a row whose item paints a different entry id or source, and a test pins the bound.
This commit is contained in:
1 parent
da00b096d2
commit
1015b16664
2 files changed
+56
-1
No files matched your search
@@ -2298,7 +2298,15 @@ function addPaintItem(record, placement, temporalAlpha, selected) {
|
||||
function pruneQueuedItemIndex() {
|
||||
for (const [sourceId, bySource] of _queuedItemBySource) {
|
||||
for (const [entryId, item] of bySource) {
|
||||
if (item.stamp !== _frameStamp) bySource.delete(entryId);
|
||||
// A pooled item that now paints another entry keeps a fresh stamp.
|
||||
const entry = item.record.entry;
|
||||
if (
|
||||
item.stamp !== _frameStamp ||
|
||||
entry.id !== entryId ||
|
||||
entry.source !== sourceId
|
||||
) {
|
||||
bySource.delete(entryId);
|
||||
}
|
||||
}
|
||||
if (bySource.size === 0) _queuedItemBySource.delete(sourceId);
|
||||
}
|
||||
|
||||
@@ -2353,3 +2353,50 @@ test('promoting an ambient entry to selected paints it once with no fading dupli
|
||||
assert.equal(paint(), 1, 'deselect restores the ambient card without re-entry cooldown');
|
||||
} finally { env.cleanup(); }
|
||||
});
|
||||
|
||||
test('the queued-card index stays bounded while card identities churn', () => {
|
||||
// The index is internal: capture the per-source map the same way the
|
||||
// projection-record test captures its map, through Map.prototype.set.
|
||||
const originalSet = Map.prototype.set;
|
||||
let queuedIndex = null;
|
||||
Map.prototype.set = function captureQueuedIndex(key, value) {
|
||||
if (typeof key === 'string' && key.startsWith('churn-card-')
|
||||
&& value && typeof value === 'object' && 'temporalAlpha' in value
|
||||
&& 'placement' in value && 'stamp' in value) {
|
||||
queuedIndex = this;
|
||||
}
|
||||
return originalSet.call(this, key, value);
|
||||
};
|
||||
const env = installMockEnvironment({ width: 400, height: 300, dpr: 1 });
|
||||
try {
|
||||
initWorldOverlay(env.viewer);
|
||||
const FRAMES = 1300;
|
||||
for (let frame = 0; frame < FRAMES; frame++) {
|
||||
// One painted card whose identity changes every frame: the same pooled
|
||||
// paint item serves every id (a vessel cohort republished as the camera
|
||||
// moves, a CCTV or radio card swapping).
|
||||
setOverlayEntries('cards', [selectedEntry(`churn-card-${frame}`, {
|
||||
position: positionAtScreen(200, 150),
|
||||
})]);
|
||||
env.advanceTime(16);
|
||||
env.postRender.raise();
|
||||
assert.equal(getQueuedOverlayEntryAlpha('cards', `churn-card-${frame}`), 1,
|
||||
'the live card is queued in the frame just painted');
|
||||
if (frame > 0) {
|
||||
assert.equal(getQueuedOverlayEntryAlpha('cards', `churn-card-${frame - 1}`), 0,
|
||||
'a stale row never reports the previous card as queued');
|
||||
}
|
||||
}
|
||||
assert.ok(queuedIndex, 'the queued-card index was never populated');
|
||||
// Rows are pruned every 600 painted frames, so with one new id per frame
|
||||
// the index holds at most one prune window of ids plus the live card.
|
||||
const bound = 600 + 1;
|
||||
assert.ok(
|
||||
queuedIndex.size <= bound,
|
||||
`queued-card index holds ${queuedIndex.size} rows after ${FRAMES} identities (bound ${bound})`,
|
||||
);
|
||||
} finally {
|
||||
Map.prototype.set = originalSet;
|
||||
env.cleanup();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user