mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-05 22:29:05 +00:00
fix: quantise the light aperture amount of moving covers (#366)
A gate or door bound to a position-reporting cover fed current_position into the light-barrier signature at toFixed(3) precision: every percent of movement produced a new fingerprint, a full physicalBodyParts recompute and a recut — up to ~100 heavy passes per gate cycle, plus LRU churn. The light pipeline now consumes one quantised amount (OPENING_LIGHT_AMOUNT_QUANTUM = 0.05, exact 0 and 1 nodes) at the single point that feeds BOTH the signature and the cut geometry, so the cache key and the drawn aperture agree by construction and a full sweep costs at most 21 recomputes. The door LEAF animation stays smooth — _openingAmt is quantised only for the light pipeline, nowhere else. Binary contact doors are byte-identical to the previous behaviour (pinned by unit). Assumption recorded in the spec: the 5% visual step of the light cut is indistinguishable on real plans; if field impressions disagree, the quantum is a one-constant change (0.02 => <=51 recomputes) or the decision falls back to a debounce. LIGHT.md §Caching documents the grid. Issue: #366 User-Visible: yes
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
pointOnBoundary, mergeRooms, splitRoomPath, polygonArea, closestPointOnBoundary, pointStrictlyInside as ptInside, islandsOf, sharedBoundary, distToSegment, outlineWithout, cutSegments, alignGuides, segmentAngle, is45, isExact45Vector, type AlignGuide, swipeTarget, clampScale, migratePdfUrls, roomFillModeOf, roomGlowOf, contentUrl,
|
||||
snapToWall, snapPointAlongPoly, openingAmount, openingShoulders, interiorPoint,
|
||||
isInteriorLightOpeningType, openingLightApertureLength, openingLightStateSignature,
|
||||
quantizeOpeningLightAmount,
|
||||
openingEntityReferences, filterOpeningEntityCandidates,
|
||||
poleOfInaccessibility, subst,
|
||||
averageLqi, fitView, declump, safeUrl, floorsOf, type FloorInfo,
|
||||
@@ -10375,7 +10376,9 @@ export class HouseplanCard extends LitElement {
|
||||
const ny = Math.cos(rad);
|
||||
const interior = onFloor([o.rx + nx * probe, o.ry + ny * probe])
|
||||
&& onFloor([o.rx - nx * probe, o.ry - ny * probe]);
|
||||
return interior ? [{ opening: o, amount: this._openingAmt(o) }] : [];
|
||||
// #366: the light pipeline consumes the quantised amount — the door
|
||||
// LEAF animation stays smooth (_openingAmt elsewhere), only light steps.
|
||||
return interior ? [{ opening: o, amount: quantizeOpeningLightAmount(this._openingAmt(o)) }] : [];
|
||||
});
|
||||
const openingStateSignature = openingLightStateSignature(
|
||||
passageStates.map(({ opening, amount }) => ({
|
||||
|
||||
@@ -342,6 +342,22 @@ export interface OpeningLightStateEntry {
|
||||
amount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* #366: one grid for the light pipeline's aperture amount. A moving cover
|
||||
* publishes current_position by the percent; unquantised it forces a full
|
||||
* barrier recompute per tick (~100 per gate cycle). Both the signature AND
|
||||
* the cut geometry consume the same quantised value, so the cache key and
|
||||
* the drawn aperture agree by construction. 0 and 1 are exact grid nodes —
|
||||
* binary contact doors are byte-identical to the pre-#366 behaviour.
|
||||
*/
|
||||
export const OPENING_LIGHT_AMOUNT_QUANTUM = 0.05;
|
||||
|
||||
export function quantizeOpeningLightAmount(amount: number): number {
|
||||
const safe = Number.isFinite(amount) ? Math.max(0, Math.min(1, amount)) : 0;
|
||||
return Math.min(1, Math.max(0,
|
||||
Math.round(safe / OPENING_LIGHT_AMOUNT_QUANTUM) * OPENING_LIGHT_AMOUNT_QUANTUM));
|
||||
}
|
||||
|
||||
/** State-only identity for interior light apertures. Structural geometry is
|
||||
* fingerprinted separately, so unrelated HA updates cannot evict barriers. */
|
||||
export function openingLightStateSignature(
|
||||
|
||||
Reference in New Issue
Block a user