No per-frame allocations in the 'doesn't connect' marks (t87)

This commit is contained in:
2026-10-29 22:06:33 -04:00
parent f88035a58f
commit de6d2c1b33
3 changed files with 26 additions and 6 deletions
+2 -2
View File
@@ -288,10 +288,10 @@ Pipes, pumps and outlets: each joined line holds one liquid as a count, not as g
Per-tick machine work: steam engines, fans, belts, filters, screw conveyors (machinesTick).
- functions: engineIntake, fanBlow, machinesTick
### src/sim/joins.js (125 lines)
### src/sim/joins.js (134 lines)
Travel-directed transport ends. Precomputed probes; world/plan queries allocate nothing. End indices stay geometric: left/right, or up/down for vertical screws.
- functions: pieceEnds, joinCandidate, endJoin, pieceJoins, endAt, joinIsDrop, joinSnap, nearMiss
- variables: JOIN_ENDS, NO_PIECE
- variables: JOIN_ENDS, NO_PIECE, NEAR_MISS_VIEW
### src/sim/conveyors.js (213 lines)
How belts, filters and screw conveyors move what is on or in them. What rests on a belt or filter rides along: the whole stack standing on the carrying surface steps one cell toward d together (belts run front of the line first, so the way ahead is clear). If a powder grain is blocked, the load above it stands still and the belt slips underneath. A filter's own material drops through it instead, unless it is already full.
+11
View File
@@ -4,6 +4,17 @@ What agents have done, newest first. Add an entry for every piece of work: the d
note or request it was for, what changed, the files touched, the tests run, and anything left
open or not verified. Keep each entry short; the git history has the details.
## 2026-10-29: t87 reuse the near-miss view (Codex)
- Reused one scratch view, its entry array and get/has methods in src/sim/joins.js;
replaced the two-row temporary array with a numeric loop. Connection rules unchanged.
- Files: src/sim/joins.js, docs/PROJECT_MAP.md, tasks/t87* and this log. Map regenerated.
- All 41 headless suites pass; every suite's before/after output matches excluding timings
(/tmp/t87-determinism.diff empty). Pixel test/play.py passes with no console errors.
Frozen shots/t87-{before,after}.png match exactly; inspected the after image and red marks.
- test/t_smooth.py fails elbow/collar and ghost-preview image checks on both original and
refactored code, with no page errors; left those existing failures outside t87's scope.
## 2026-10-29: t83 remove old-save conversions (Codex)
- Removed only spring, solid-pipe, single-material-filter and foreground-tree conversions
+13 -4
View File
@@ -108,16 +108,25 @@ function joinSnap(code, v, cells) {
// A drop join counts as connected. The moved block is tried through a small override view of
// `planned`, so ghost maps are never copied.
const NO_PIECE = [0, 0];
// Synchronous join queries never retain this scratch view or call nearMiss recursively.
const NEAR_MISS_VIEW = {
source: -1, moved: -1, planned: null, entry: [0, 0],
get(k) {
return k === this.source ? NO_PIECE : k === this.moved ? this.entry : this.planned ? this.planned.get(k) : undefined;
},
has(k) { return this.get(k) !== undefined; }
};
function nearMiss(bx, by, end, planned = null) {
const b = by * BW + bx, p = planned && planned.get(b), code = p ? p[0] : blockP[b], v = p ? p[1] : blockV[b];
const own = pieceEnds(code, v);
if (!own[end] || endJoin(bx, by, end, planned) >= 0) return 0;
const entry = [code, v];
for (const dy of [-1, 1]) {
const view = NEAR_MISS_VIEW;
view.source = b; view.planned = planned;
view.entry[0] = code; view.entry[1] = v;
for (let dy = -1; dy <= 1; dy += 2) {
const y = by + dy, nb = y * BW + bx;
if (y < 0 || y >= BH || blockP[nb] || (planned && planned.get(nb))) continue;
const view = { get: k => k === b ? NO_PIECE : k === nb ? entry : planned ? planned.get(k) : undefined };
view.has = k => view.get(k) !== undefined;
view.moved = nb;
const j = endJoin(bx, y, end, view);
if (j >= 0 && !joinIsDrop(bx, y, end, j, view) && (own[end].diagonal || endAt(j >> 1, j & 1, view).diagonal)) return dy;
}