fix: getTopologyValue off-by-one bug in clause-based topology evaluators
getTopologyValue used subject ID as direct array index (arr[subjectId] ?? 0), but solver subject IDs are 1-indexed while topology arrays are 0-indexed parallel arrays. This produced wrong results for any subjectId != position+1. Fixed by using world.subjects.ids.indexOf(subjectId) to map subject ID to array position, matching the predicate evaluator's getTopologyValueBySubject pattern. Affected callers: evaluateAttachedToScrollContainer, evaluateInStackingContext. The predicate-based evaluators in predicates.ts were already correct.
This commit is contained in:
@@ -33,11 +33,16 @@ function result(
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely read a topology value indexed by subject id.
|
||||
* Returns 0 when the subject is out of bounds (treated as "no relation").
|
||||
* Safely read a topology value for a given solver subject ID.
|
||||
*
|
||||
* Solver subject IDs are 1-indexed; topology arrays are 0-indexed parallel
|
||||
* to world.subjects.ids. Returns 0 when the subject is not found (treated as
|
||||
* "no relation").
|
||||
*/
|
||||
function getTopologyValue(arr: number[], subjectId: number): number {
|
||||
return arr[subjectId] ?? 0;
|
||||
function getTopologyValue(world: GeometryWorld, arr: number[], subjectId: number): number {
|
||||
const idx = world.subjects.ids.indexOf(subjectId);
|
||||
if (idx < 0 || idx >= arr.length) return 0;
|
||||
return arr[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,6 +114,7 @@ export function evaluateAttachedToScrollContainer(
|
||||
}
|
||||
|
||||
const scrollContainerId = getTopologyValue(
|
||||
world,
|
||||
world.topology.scrollContainerOf,
|
||||
subjectRef,
|
||||
);
|
||||
@@ -139,7 +145,7 @@ export function evaluateInStackingContext(
|
||||
});
|
||||
}
|
||||
|
||||
const sCtx = getTopologyValue(world.topology.stackingContextOf, subjectRef);
|
||||
const sCtx = getTopologyValue(world, world.topology.stackingContextOf, subjectRef);
|
||||
|
||||
if (referenceRef === undefined) {
|
||||
const pass = sCtx !== 0;
|
||||
@@ -152,7 +158,7 @@ export function evaluateInStackingContext(
|
||||
);
|
||||
}
|
||||
|
||||
const rCtx = getTopologyValue(world.topology.stackingContextOf, referenceRef);
|
||||
const rCtx = getTopologyValue(world, world.topology.stackingContextOf, referenceRef);
|
||||
const pass = sCtx !== 0 && sCtx === rCtx;
|
||||
|
||||
return result(
|
||||
|
||||
Reference in New Issue
Block a user