← back to Quadrille Showroom
snapshot before Slice 2: cladToken boot-race guard (in-flight onload invalidation)
13c193b7524f798636b3fc0d241e66057725db04 · 2026-06-28 17:07:03 -0700 · Steve Abrams
Files touched
Diff
commit 13c193b7524f798636b3fc0d241e66057725db04
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jun 28 17:07:03 2026 -0700
snapshot before Slice 2: cladToken boot-race guard (in-flight onload invalidation)
---
public/js/showroom.js | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/public/js/showroom.js b/public/js/showroom.js
index 4ebdcf7..74afd17 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -746,13 +746,22 @@ function addWall(x, y, z, w, h, rotY, mat) {
// WALL CLADDING — render the selected pattern onto the room walls
// ============================================================
const PHYS_TILE_M = 0.686; // assumed physical tile ≈ 27" so the pattern reads at room scale
+// Monotonic clad token: every cladWalls() bumps it; a deferred image onload only paints
+// if it's still the latest request AND walls should be clad (a wing is focused). This
+// kills the boot race where a transient Hero focus's async onload repainted the walls
+// AFTER enterGuidedDefault reverted them back to neutral cream (Slice-1 boot invariant).
+let _cladToken = 0;
+function _cladStillWanted(token) {
+ return token === _cladToken && (wallsAutoClad || focusedWing);
+}
function cladWalls(imageUrl, isSeamlessTile) {
if (!imageUrl || !roomWalls.length) return;
+ const token = ++_cladToken;
const cached = imageTexCache[imageUrl];
- if (cached && cached.texture && cached.texture.image) { applyWallImage(cached.texture.image, isSeamlessTile); return; }
+ if (cached && cached.texture && cached.texture.image) { if (_cladStillWanted(token)) applyWallImage(cached.texture.image, isSeamlessTile); return; }
const src = imageUrl.charAt(0) === '/' ? imageUrl : ('/api/proxy/image?url=' + encodeURIComponent(imageUrl));
const img = new Image();
- img.onload = () => applyWallImage(img, isSeamlessTile);
+ img.onload = () => { if (_cladStillWanted(token)) applyWallImage(img, isSeamlessTile); };
img.src = src;
}
@@ -778,6 +787,7 @@ function applyWallImage(img, isSeamlessTile) {
}
function revertWalls() {
+ _cladToken++; // invalidate any in-flight clad onload (boot-race guard)
roomWalls.forEach(w => {
w.mesh.material = w.origMat;
if (w.cladMat && w.cladMat.map) { w.cladMat.map.dispose(); w.cladMat.map = null; }
← 04ca167 /5x sweep-1 report: Slice-1 build verified clean (HTTP/rende
·
back to Quadrille Showroom
·
auto-save: 2026-06-28T17:15:46 (1 files) — public/js/showroo 966628f →