mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 04:09:17 +00:00
refactor: one function owns the junction geometry of a space (#229 r2 M1)
Дефект High-1 был одинаковым в двух местах — и в живом рисовании, и в
«Оптимизировать планы», — потому что каждый вызывающий собирал геометрию
примыканий сам. Ревью r2 справедливо заметило, что и защита получилась
однобокой: юнит и мутант сторожили только оптимизатор, а путь карты — тот, где
дефект и был виден пользователю, — не сторожил никто. Заплатка в виде второго
мутанта-близнеца оставила бы причину на месте: два списка координат, которые
обязаны совпадать, но ничем не связаны.
Поэтому геометрия переехала в `spaceMergeGeometry(space, { excludeDraftId })`:
один источник комнат, колонн и концов черновиков, одни координаты, одно место,
где можно ошибиться. Оба вызывающих теперь строчка вызова.
Покрытие идёт за причиной, а не за симптомом: три юнита в
`test/wall-merge.test.mjs` проверяют масштаб полигонов (включая комнаты в форме
x/y/w/h и комнату без геометрии), исключение активного черновика и сам T-стык к
середине стороны комнаты. Мутанты `partition-merge-rescales-rooms` и
`chain-merge-sees-own-draft` перенацелены на общий модуль и теперь краснеют для
обоих путей сразу: 2 и 1 падение, проверено применением патча.
Сценарий с комнатой в смоке пробовал — не взлетел: рисование в комнату
поднимает `_offerWallFaces`, и цепочка не завершается штатно. Ломать смок под
тест не стал, юниты общего модуля покрывают оба пути честнее.
Issue: #229
User-Visible: no
This commit is contained in:
+2
-15
@@ -24,7 +24,7 @@ import {
|
||||
degradeWalls, normalizeWallIntervals, rekeyWallsAfterMove, roomWallProfile,
|
||||
setWallThickness, type WallEntry,
|
||||
} from './wall-thickness';
|
||||
import { applyOpeningMoves, mergeCollinearPartitions } from './wall-merge';
|
||||
import { applyOpeningMoves, mergeCollinearPartitions, spaceMergeGeometry } from './wall-merge';
|
||||
|
||||
/** Bump when a new lossless maintenance pass is added. */
|
||||
export const PLAN_MODEL_VERSION = 6;
|
||||
@@ -502,20 +502,7 @@ export function optimizePlans(configIn: any, layoutIn: Record<string, any>): Opt
|
||||
// plan finally loses them — explicitly, with a report and an undo (#229).
|
||||
const partitionMerge = mergeCollinearPartitions(space.partitions || [], {
|
||||
pitch: GRID_STEP_N,
|
||||
geometry: {
|
||||
// Rooms are stored in the same coordinates as partitions: `roomPoly`
|
||||
// hands back the raw config polygon, so scaling it here would push
|
||||
// every room into a corner and no junction would ever be found
|
||||
// (review CODE-REVIEW-229-r1, High-1).
|
||||
roomPolygons: (space.rooms || [])
|
||||
.map((room: any) => roomPoly(room))
|
||||
.filter((poly: number[][] | null): poly is number[][] => !!poly),
|
||||
columns: space.wall_columns || [],
|
||||
draftEnds: (space.room_drafts || []).flatMap((draft: any) => {
|
||||
const points = draft?.points || [];
|
||||
return points.length ? [points[0], points[points.length - 1]] : [];
|
||||
}),
|
||||
},
|
||||
geometry: spaceMergeGeometry(space),
|
||||
});
|
||||
if (partitionMerge.merged) {
|
||||
partitionsMerged += partitionMerge.merged;
|
||||
|
||||
Reference in New Issue
Block a user