mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-05 06:08:59 +00:00
File diff suppressed because one or more lines are too long
Vendored
+115
-115
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
"version": 1,
|
||||
"fixture": "synthetic-only",
|
||||
"chromium": "151.0.7922.34",
|
||||
"sourceFingerprint": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceFingerprint": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"captureScriptSha256": "ce2e9542fed9dade3085be87d16f69adb2ac8262893ad78ad966b1b9673f2983",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "36223106c073f07d8cc3ecf8eaab37192ebb2687daba65c5c21047d0b7890de0"
|
||||
},
|
||||
"view-touch": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "41e3ba67f8db0e98f26f484293af83ef937c369ca5ca6a59a3350d8954c906f4"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "0dc024726327f60f4a9ceaf3044381691f81f1090af81d1812e870f22d9343ba"
|
||||
},
|
||||
"room-contour-close": {
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "44cfaa95bd51e2cd628400e28db0ad8b2f0cd904385845bd402494f3f5c0d93c"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "e0662429b423fb74151b583dcc2c8635b001b637d03bbf7a6b16aec46399c3f8"
|
||||
},
|
||||
"device-editor": {
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "d0ffd31ce80bfde21ab75da356a5fc1af38246f2b301030880320620c228d89d"
|
||||
},
|
||||
"device-display-preview": {
|
||||
@@ -80,7 +80,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "2cdabae1f89c3286e4fac0ce30f757ee1690b707ab8a5488748b7cd420626160"
|
||||
},
|
||||
"background-editor": {
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "30147bb00a90eea7136b4cee30995f6e6a9217b5132f3e8d3ad7471413b1af8a"
|
||||
},
|
||||
"room-card": {
|
||||
@@ -102,7 +102,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "029a3e69ec647a8a370d99e6bb7f9225833c526739076022f6b52ba54bff30ea"
|
||||
},
|
||||
"device-info": {
|
||||
@@ -113,7 +113,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "f2df45c488a90c46b3483701e59600abbf3ba470aae7d9d7a17fd6e232f600f8",
|
||||
"sourceSha256": "5bd5c452cf113bb83c9eb8f3f0cb2905e7980ced18b1afe6f8919cc93a80a4cc",
|
||||
"imageSha256": "dd492f53150b7149085daada5cce9eeae9bde9e7ea1d86679a54b3041f72f517"
|
||||
}
|
||||
}
|
||||
|
||||
+91
-26
@@ -67,7 +67,7 @@ import {
|
||||
import {
|
||||
degradeWalls, rekeyWallsAfterMoveChecked, wallRecordCarrierViolations,
|
||||
setWallThickness, setWallThicknessForRoom, cmToField, wallCmToUnits,
|
||||
wallEdgeBodies, wallBodiesGeometry, wallBodiesUnionPath,
|
||||
wallEdgeBodies, wallBodiesGeometry, wallBodiesGeometryPath, wallBodiesUnionPath,
|
||||
floorFootprintGeometry,
|
||||
innerContourForRoom, roomWallProfile, outsetContour,
|
||||
openingInnerFaceOffsetFromIndex, openingTunnelGeometriesFromIndex,
|
||||
@@ -1578,10 +1578,31 @@ class HouseplanCard extends LitElement {
|
||||
private _physicalPickCycle: {
|
||||
signature: string; index: number; x: number; y: number; at: number;
|
||||
} | null = null;
|
||||
private _wallUnionCache: {
|
||||
private _wallUnionCacheValue: {
|
||||
key: string;
|
||||
value: ReturnType<typeof wallBodiesUnionPath>;
|
||||
} | null = null;
|
||||
/** A floor switch is presentation-only: retain the bounded structural union
|
||||
* for recently shown floors instead of rebuilding it on every tab click. */
|
||||
private _wallUnionPool = new Map<string, {
|
||||
key: string;
|
||||
value: ReturnType<typeof wallBodiesUnionPath>;
|
||||
}>();
|
||||
/** Keep the historical cache property observable by performance/smoke
|
||||
* contracts. Explicit test/product invalidation also clears the pool. */
|
||||
private get _wallUnionCache(): {
|
||||
key: string;
|
||||
value: ReturnType<typeof wallBodiesUnionPath>;
|
||||
} | null {
|
||||
return this._wallUnionCacheValue;
|
||||
}
|
||||
private set _wallUnionCache(value: {
|
||||
key: string;
|
||||
value: ReturnType<typeof wallBodiesUnionPath>;
|
||||
} | null) {
|
||||
this._wallUnionCacheValue = value;
|
||||
if (value === null) this._wallUnionPool.clear();
|
||||
}
|
||||
private _isoGeometryCache = new Map<string, {
|
||||
geometry: IsoWallGeometry;
|
||||
floor: IsoFloorGeometry;
|
||||
@@ -8913,14 +8934,46 @@ class HouseplanCard extends LitElement {
|
||||
if (wallRecordCarrierViolations(
|
||||
changedWalls, wallCarriers, this._wallKeyPitch, NORM_W, s.walls || [],
|
||||
).length) return { ok: false, reason: 'wall-metadata' };
|
||||
if (!this._rszSpaceCandidateRenderable(this._space, sp)) {
|
||||
const preflight = this._rszSpaceCandidateGeometry(this._space, sp);
|
||||
if (!preflight.ok) {
|
||||
return { ok: false, reason: 'physical-geometry' };
|
||||
}
|
||||
this._rszPreview = { space: this._space, sp };
|
||||
this._cfgEpoch++;
|
||||
if (preflight.wallGeometry) {
|
||||
const projected = wallBodiesGeometryPath(preflight.wallGeometry);
|
||||
if (projected) {
|
||||
const key = `${this._space}|${this._cfgEpoch}|${sp.rooms.length}`;
|
||||
const entry = { key, value: projected };
|
||||
lruWrite(this._wallUnionPool, key, entry, 8);
|
||||
this._wallUnionCache = entry;
|
||||
}
|
||||
}
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
/** Validate once and retain the exact geometry pass for the preview render. */
|
||||
private _rszSpaceCandidateGeometry(spaceId: string, sp: any): {
|
||||
ok: boolean;
|
||||
wallGeometry: ReturnType<typeof wallBodiesGeometry> | null;
|
||||
} {
|
||||
if (!this._serverCfg) return { ok: false, wallGeometry: null };
|
||||
const candidate = {
|
||||
...this._serverCfg,
|
||||
spaces: this._serverCfg.spaces.map((space: any) =>
|
||||
space.id === spaceId ? sp : space),
|
||||
} as ServerConfig;
|
||||
let wallGeometry: ReturnType<typeof wallBodiesGeometry> | null = null;
|
||||
try {
|
||||
const check = this._checkSpacePhysicalGeometry(
|
||||
candidate, spaceId, (geometry) => { wallGeometry = geometry; },
|
||||
);
|
||||
return { ok: check.ok, wallGeometry };
|
||||
} catch {
|
||||
return { ok: false, wallGeometry: null };
|
||||
}
|
||||
}
|
||||
|
||||
/** Fail-closed check for one exact candidate through the common barrier. */
|
||||
private _rszSpaceCandidateRenderable(spaceId: string, sp: any): boolean {
|
||||
if (!this._serverCfg) return false;
|
||||
@@ -9117,7 +9170,6 @@ class HouseplanCard extends LitElement {
|
||||
const imperial = this.hass?.config?.unit_system?.length === 'mi';
|
||||
const ids = plan.roomIds;
|
||||
const walls = this._spaceWalls;
|
||||
const openCuts = this._openCuts();
|
||||
const physical = this._physicalBodiesR();
|
||||
const base = this._baseVb();
|
||||
const currentView = this._view && this._view.w > 0 && this._view.h > 0
|
||||
@@ -9145,11 +9197,11 @@ class HouseplanCard extends LitElement {
|
||||
);
|
||||
for (const id of ids) {
|
||||
const poly = res.polys[id] || g.rooms.find((r) => r.id === id)!.poly;
|
||||
const floor = walls.length
|
||||
? (innerContourForRoom(
|
||||
Object.entries(res.polys).map(([rid, p]) => ({ id: rid, poly: p })),
|
||||
id, walls, openCuts, this._wallKeyPitch, this._cellCm, this._gridPitch, NORM_W,
|
||||
) || poly)
|
||||
// The preview is already the active render model. Reuse the same shared
|
||||
// masonry union + contour cache that the following render consumes;
|
||||
// rebuilding both independently here doubled one Resize frame.
|
||||
const floor = walls.length && space
|
||||
? (this._innerRoomContour(space, id) || poly)
|
||||
: poly;
|
||||
const m2 = physical.length
|
||||
? geometryArea(floorMinusBodies(floor, physical))
|
||||
@@ -11567,13 +11619,19 @@ class HouseplanCard extends LitElement {
|
||||
const openings = this._roomWallOpeningInputs();
|
||||
const unionKey = `${this._space}|${this._cfgEpoch}|${space.rooms.length}`;
|
||||
if (!this._wallUnionCache || this._wallUnionCache.key !== unionKey) {
|
||||
this._wallUnionCache = {
|
||||
key: unionKey,
|
||||
value: wallBodiesUnionPath(
|
||||
space.rooms, walls, openCuts, openings,
|
||||
this._wallKeyPitch, this._cellCm, this._gridPitch, NORM_W, extras,
|
||||
),
|
||||
};
|
||||
const cached = lruRead(this._wallUnionPool, unionKey);
|
||||
if (cached.hit) this._wallUnionCache = cached.value;
|
||||
else {
|
||||
const entry = {
|
||||
key: unionKey,
|
||||
value: wallBodiesUnionPath(
|
||||
space.rooms, walls, openCuts, openings,
|
||||
this._wallKeyPitch, this._cellCm, this._gridPitch, NORM_W, extras,
|
||||
),
|
||||
};
|
||||
lruWrite(this._wallUnionPool, unionKey, entry, 8);
|
||||
this._wallUnionCache = entry;
|
||||
}
|
||||
}
|
||||
return this._wallUnionCache.value;
|
||||
}
|
||||
@@ -11597,23 +11655,21 @@ class HouseplanCard extends LitElement {
|
||||
roomId: string,
|
||||
openCuts: number[][] = this._openCuts(),
|
||||
roomWalls = this._wallUnionGeometry()?.roomGeom,
|
||||
multiWallNodes = this._wallUnionGeometry()?.multiWallNodes,
|
||||
): number[][] | null {
|
||||
const cutsKey = openCuts.map((cut) => cut.join(',')).join(';');
|
||||
const key = `${space.id}|${this._cfgEpoch}|${roomId}|${cutsKey}`;
|
||||
// Editor previews can replace room polygons without advancing the saved
|
||||
// config epoch. Cache only the immutable View surface; otherwise a Resize
|
||||
// drag would keep painting (and hit-testing) the pre-drag contour.
|
||||
const cacheable = this._mode === 'view' && !this._rszPreview;
|
||||
if (cacheable) {
|
||||
const cached = lruRead(this._innerContourCache, key);
|
||||
if (cached.hit) return cached.value;
|
||||
}
|
||||
// Resize advances the structural epoch before publishing every preview,
|
||||
// so editor and View consumers can safely share one per-epoch answer.
|
||||
const cached = lruRead(this._innerContourCache, key);
|
||||
if (cached.hit) return cached.value;
|
||||
const value = innerContourForRoom(
|
||||
space.rooms, roomId, this._spaceWalls, openCuts,
|
||||
this._wallKeyPitch, this._cellCm, this._gridPitch, NORM_W,
|
||||
roomWalls,
|
||||
multiWallNodes,
|
||||
);
|
||||
if (cacheable) lruWrite(this._innerContourCache, key, value, 600);
|
||||
lruWrite(this._innerContourCache, key, value, 600);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -15614,9 +15670,18 @@ class HouseplanCard extends LitElement {
|
||||
}
|
||||
|
||||
/** One strict production source shared by editor commits and stale rechecks. */
|
||||
private _checkSpacePhysicalGeometry(config: ServerConfig, spaceId: string) {
|
||||
private _checkSpacePhysicalGeometry(
|
||||
config: ServerConfig,
|
||||
spaceId: string,
|
||||
captureWallGeometry?: (
|
||||
geometry: ReturnType<typeof wallBodiesGeometry>,
|
||||
) => void,
|
||||
) {
|
||||
return checkSpacePhysicalGeometry(config, spaceId, {
|
||||
fallbackSpaceName: (index) => this._t('gs.align_preflight_space', { n: String(index) }),
|
||||
captureWallGeometry: captureWallGeometry
|
||||
? (_input, geometry) => captureWallGeometry(geometry)
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,12 @@ export interface CheckOptimizeGeometryOptions {
|
||||
wallPass?: typeof wallBodiesGeometry;
|
||||
floorPass?: typeof floorFootprintGeometry;
|
||||
fingerprint?: typeof contentFingerprint;
|
||||
/** Internal reuse seam: receives the exact successful wall pass without
|
||||
* adding private plan geometry to the serializable preflight result. */
|
||||
captureWallGeometry?: (
|
||||
input: SpacePhysicalGeometryInputs,
|
||||
geometry: ReturnType<typeof wallBodiesGeometry>,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export interface SpacePhysicalGeometryResult extends OptimizeSpaceGeometryCheck {
|
||||
@@ -392,6 +398,7 @@ export function checkOptimizeGeometry(
|
||||
spaces.push({ ...identity, status: 'failed', reason: 'wall-failed-core' });
|
||||
continue;
|
||||
}
|
||||
options.captureWallGeometry?.(input, united);
|
||||
}
|
||||
|
||||
if (input.space.rooms.length && united?.paperGeom == null) {
|
||||
|
||||
+28
-6
@@ -41,6 +41,8 @@ export interface WallBodiesGeometryResult {
|
||||
paperGeom: any;
|
||||
depthUnits: number;
|
||||
openingIndex: OpeningWallIndex | null;
|
||||
/** Canonical junction topology reused by per-room inner contours. */
|
||||
multiWallNodes: MultiWallNodeMap | null;
|
||||
degradedExtraCount: number;
|
||||
}
|
||||
|
||||
@@ -2416,7 +2418,7 @@ export function multiWallNodeAt(
|
||||
|| a.point[0] - b.point[0] || a.point[1] - b.point[1])[0] || null;
|
||||
}
|
||||
|
||||
function multiWallNodesForGeometry(
|
||||
export function multiWallNodesForGeometry(
|
||||
rooms: any[],
|
||||
walls: WallEntry[] | null | undefined,
|
||||
openCuts: number[][],
|
||||
@@ -2743,6 +2745,8 @@ export function innerContourForRoom(
|
||||
coordScale = 1,
|
||||
/** Canonical room-wall masonry before opening cuts; pass the render cache. */
|
||||
sharedRoomWallGeometry?: any,
|
||||
/** Canonical junction topology from the same wall-geometry pass. */
|
||||
sharedMultiWallNodes?: MultiWallNodeMap | null,
|
||||
): number[][] | null {
|
||||
const room = (rooms || []).find((r) => r?.id === roomId);
|
||||
const poly = roomPoly(room);
|
||||
@@ -2750,7 +2754,7 @@ export function innerContourForRoom(
|
||||
if (!walls?.length) return poly.map((p) => [p[0], p[1]]);
|
||||
const pr = roomWallProfile(rooms, roomId, walls, openCuts, pitch, cellCm, gridPitch, coordScale);
|
||||
if (!pr || !pr.offsets.some((o) => o > 0)) return poly.map((p) => [p[0], p[1]]);
|
||||
const multiWallNodes = multiWallNodesForGeometry(
|
||||
const multiWallNodes = sharedMultiWallNodes || multiWallNodesForGeometry(
|
||||
rooms, walls, openCuts, pitch, cellCm, gridPitch, coordScale,
|
||||
);
|
||||
const inset = insetContour(pr.poly, pr.offsets, multiWallNodes);
|
||||
@@ -3602,7 +3606,7 @@ export function wallBodiesGeometry(
|
||||
): WallBodiesGeometryResult {
|
||||
if (!walls?.length && !extraBodies.length) return {
|
||||
status: 'not-applicable', geom: [], components: [], roomGeom: [], paperGeom: [],
|
||||
depthUnits: 0, openingIndex: null, degradedExtraCount: 0,
|
||||
depthUnits: 0, openingIndex: null, multiWallNodes: null, degradedExtraCount: 0,
|
||||
};
|
||||
const roomRings: MultiWallRoomRing[] = [];
|
||||
const multiWallNodes = multiWallNodesForGeometry(
|
||||
@@ -3832,14 +3836,14 @@ export function wallBodiesGeometry(
|
||||
return {
|
||||
status: degradedExtraCount || degradedCoreCount ? 'degraded-extra' : 'ok',
|
||||
geom: primary, components, roomGeom, paperGeom,
|
||||
depthUnits: maxDepth, openingIndex,
|
||||
depthUnits: maxDepth, openingIndex, multiWallNodes,
|
||||
degradedExtraCount: degradedExtraCount + degradedCoreCount,
|
||||
};
|
||||
} catch {
|
||||
operations.onCoreFailure?.(corePhase);
|
||||
return {
|
||||
status: 'failed-core', geom: [], components: [], roomGeom: [], paperGeom: [],
|
||||
depthUnits: maxDepth, openingIndex: null, degradedExtraCount: 0,
|
||||
depthUnits: maxDepth, openingIndex: null, multiWallNodes, degradedExtraCount: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3863,6 +3867,7 @@ export function wallBodiesUnionPath(
|
||||
paths: readonly { id: string; d: string; fillRule: 'evenodd' }[];
|
||||
components: readonly WallGeometryComponent[];
|
||||
roomGeom: any;
|
||||
multiWallNodes: MultiWallNodeMap | null;
|
||||
paperD: string;
|
||||
depthUnits: number;
|
||||
fillRule: 'evenodd' | 'nonzero';
|
||||
@@ -3872,6 +3877,23 @@ export function wallBodiesUnionPath(
|
||||
rooms, walls, openCuts, openings, pitch, cellCm, gridPitch, coordScale, extraBodies,
|
||||
operations,
|
||||
);
|
||||
return wallBodiesGeometryPath(united);
|
||||
}
|
||||
|
||||
/** Project one already validated wall-geometry pass into the SVG payload. */
|
||||
export function wallBodiesGeometryPath(
|
||||
united: WallBodiesGeometryResult,
|
||||
): {
|
||||
status: 'ok' | 'degraded-extra';
|
||||
d: string;
|
||||
paths: readonly { id: string; d: string; fillRule: 'evenodd' }[];
|
||||
components: readonly WallGeometryComponent[];
|
||||
roomGeom: any;
|
||||
multiWallNodes: MultiWallNodeMap | null;
|
||||
paperD: string;
|
||||
depthUnits: number;
|
||||
fillRule: 'evenodd' | 'nonzero';
|
||||
} | null {
|
||||
if (united.status === 'failed-core' || united.status === 'not-applicable') return null;
|
||||
const paths = united.components.map((component) => ({
|
||||
id: component.id, d: polyclipToPathD(component.geom), fillRule: 'evenodd' as const,
|
||||
@@ -3880,7 +3902,7 @@ export function wallBodiesUnionPath(
|
||||
const paperD = polyclipToPathD(united.paperGeom);
|
||||
if (paths.length) return {
|
||||
status: united.status, d, paths, components: united.components,
|
||||
roomGeom: united.roomGeom, paperD,
|
||||
roomGeom: united.roomGeom, multiWallNodes: united.multiWallNodes, paperD,
|
||||
depthUnits: united.depthUnits, fillRule: 'evenodd',
|
||||
};
|
||||
// successful empty result: do not resurrect raw rings
|
||||
|
||||
@@ -92,9 +92,12 @@ test('room inner faces are structurally cached and shared by both fill layers',
|
||||
const helperEnd = source.indexOf('\n /**', helperStart);
|
||||
assert.ok(helperStart >= 0 && helperEnd > helperStart, 'inner-contour cache helper is present');
|
||||
const helper = source.slice(helperStart, helperEnd);
|
||||
assert.match(helper, /const cacheable = this\._mode === 'view' && !this\._rszPreview;/);
|
||||
assert.match(helper, /lruRead\(this\._innerContourCache, key\)/);
|
||||
assert.match(helper, /lruWrite\(this\._innerContourCache, key, value, 600\)/);
|
||||
assert.match(helper, /multiWallNodes/);
|
||||
assert.match(source, /lruRead\(this\._wallUnionPool, unionKey\)/);
|
||||
assert.match(source, /lruWrite\(this\._wallUnionPool, unionKey, entry, 8\)/);
|
||||
assert.match(source, /wallBodiesGeometryPath\(preflight\.wallGeometry\)/);
|
||||
|
||||
const glowStart = source.indexOf('private _renderGlowBaseRooms(');
|
||||
const glowEnd = source.indexOf('\n private _renderWallBodies(', glowStart);
|
||||
|
||||
@@ -153,6 +153,15 @@ test('#278 strict one-space barrier rejects degraded render-safe geometry', () =
|
||||
id: 'strict', title: 'Strict', view_box: [0, 0, 1, 1],
|
||||
rooms: [room()], walls: [wall()],
|
||||
}]);
|
||||
let captured = null;
|
||||
const accepted = checkSpacePhysicalGeometry(config, 'strict', {
|
||||
captureWallGeometry: (input, geometry) => { captured = { input, geometry }; },
|
||||
});
|
||||
assert.equal(accepted.ok, true);
|
||||
assert.equal(captured?.input?.space?.id, 'strict');
|
||||
assert.equal(captured?.geometry?.status, 'ok');
|
||||
assert.ok(captured?.geometry?.multiWallNodes);
|
||||
|
||||
const degraded = checkSpacePhysicalGeometry(config, 'strict', {
|
||||
wallPass: () => ({
|
||||
status: 'degraded-extra', geom: [], components: [], roomGeom: [], paperGeom: [],
|
||||
|
||||
Reference in New Issue
Block a user