Archify Diagram Viewer 0.1.0
VS Code extension that previews Archify diagrams from their JSON sources (live, as you type) and opens rendered Archify HTML in a viewer tab. Bundles the Archify 3.0.1 renderer and runs it on VS Code's Node runtime. Adds validation diagnostics, JSON schema help, source-link navigation, export saving, render-to-file and open-in-browser commands. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/** Uniform spatial grid for "which items can this box reach" queries (#8). */
|
||||
|
||||
// A cell box wider than this is not worth walking: the query returns every
|
||||
// inserted item instead, which stays a superset of what the box reaches.
|
||||
const DEFAULT_MAX_CELLS = 4096;
|
||||
|
||||
export function createSpatialGrid(cellSize, { maxCells = DEFAULT_MAX_CELLS } = {}) {
|
||||
const buckets = new Map();
|
||||
const items = [];
|
||||
// Items whose own box cannot be walked are candidates for every query.
|
||||
const overflow = [];
|
||||
const keyOf = (x, y) => x + ':' + y;
|
||||
const rangeOf = (box) => ({
|
||||
x0: Math.floor(box.minX / cellSize), x1: Math.floor(box.maxX / cellSize),
|
||||
y0: Math.floor(box.minY / cellSize), y1: Math.floor(box.maxY / cellSize),
|
||||
});
|
||||
// Finite coordinates can still land outside the safe-integer range, where
|
||||
// incrementing an index no longer advances it; and a legal coordinate can
|
||||
// name more cells than the grid is worth. Both cases stay out of the buckets
|
||||
// and are answered by the item list, so they never hang or allocate.
|
||||
const walkable = (range) => Number.isSafeInteger(range.x0) && Number.isSafeInteger(range.x1)
|
||||
&& Number.isSafeInteger(range.y0) && Number.isSafeInteger(range.y1)
|
||||
&& (range.x1 - range.x0 + 1) * (range.y1 - range.y0 + 1) <= maxCells;
|
||||
|
||||
return {
|
||||
insert(box, item) {
|
||||
items.push(item);
|
||||
const range = rangeOf(box);
|
||||
if (!walkable(range)) {
|
||||
overflow.push(item);
|
||||
return;
|
||||
}
|
||||
for (let x = range.x0; x <= range.x1; x += 1) {
|
||||
for (let y = range.y0; y <= range.y1; y += 1) {
|
||||
const key = keyOf(x, y);
|
||||
let bucket = buckets.get(key);
|
||||
if (!bucket) { bucket = []; buckets.set(key, bucket); }
|
||||
bucket.push(item);
|
||||
}
|
||||
}
|
||||
},
|
||||
query(box) {
|
||||
const range = rangeOf(box);
|
||||
if (!walkable(range)) return items.slice();
|
||||
const seen = new Set();
|
||||
const found = [];
|
||||
for (let x = range.x0; x <= range.x1; x += 1) {
|
||||
for (let y = range.y0; y <= range.y1; y += 1) {
|
||||
const bucket = buckets.get(keyOf(x, y));
|
||||
if (!bucket) continue;
|
||||
for (const item of bucket) {
|
||||
if (seen.has(item)) continue;
|
||||
seen.add(item);
|
||||
found.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const item of overflow) {
|
||||
if (seen.has(item)) continue;
|
||||
seen.add(item);
|
||||
found.push(item);
|
||||
}
|
||||
return found;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user