Merge remote-tracking branch 'origin/dev' into sub_laptop_7

This commit is contained in:
2026-10-19 07:36:43 +09:00
21 changed files with 1478 additions and 111 deletions
+36 -3
View File
@@ -8,9 +8,17 @@
* 입력 = 관 알림(배수유역도 · B06 관 목록) · 구조물(보기 고침 · 저장분) · 종류 표 · 측점 간격 · 추가 측점(가게)
* 관 id 장부 = 관 고정 id 가 쥔 세션 id 를 그 자리로(411-B) · 헛 id 정리(411-E) — 어느 보기에서 고쳐도
* 계획고 편집 옮김(사라진 측점 → 새 측점 · 213-2) = 사용자 고침만 · 노선 따라감(`follow`)은 안 옮김(계산 묶음 몫 · 349-0d)
* 소단 사본(세션 `berm`) = 구조물 소단 구간 — 쓰는 자리 여기 하나(B05 만 열어도 · 같으면 안 씀 · 쓰면 cross 한 번 · 467)
* ========================================================================== */
import { useDesignStore } from "./design_store";
import { pageRouteId } from "./design_page_route";
import { readState } from "../b_page_state";
import {
bermSpansFromStructures,
writeBermSpans,
type BermSpan,
} from "../../B06_Section/B06_Section_UI_Page_Persist";
import { pipeIdAt, placePipeIds, prunePipeIds, withPipeIds } from "./design_pipe_ids";
import { plannedIrregular } from "./design_structure_status";
import { planStations } from "../../common_util/common_util_structure_station";
@@ -85,8 +93,9 @@ export function createFacilityLane(
): FacilityLane {
const store = useDesignStore(projectId, null);
let types: StructureType[] = [];
let stored: StructureInstance[] = [];
let stored: StructureInstance[] | null = null;
let structures: StructureInstance[] = [];
let structuresKnown = false; // 구조물을 받기 전 = 소단 사본 안 씀(빈 목록으로 저장분 소단을 지우지 않게)
/** 마지막 관 알림 — 노선 따라감 · 관 초안이 바뀌면 이것을 초안 측점으로 다시 맞춤. */
let reported: LanePipe[] | null = null;
let pipes: LanePipe[] = [];
@@ -139,6 +148,23 @@ export function createFacilityLane(
const marks = (): StructureInstance[] => [...structures, ...pipesToStructureMarks(pipes)];
/** 소단 사본 = 지금 구조물의 소단 구간(467 · 사본 없는 동안 다시 셈 = 저장분 `design.berm`) · 같으면 안 씀 ·
* 쓰면 저장 노선 cross 한 번 더(같은 값 측점은 다시 셈 기억이 건너뜀 · 묶음은 늦게 불러옴 · 순환 없음). */
function syncBerm(): void {
const routeId = pageRouteId(projectId);
if (!structuresKnown || routeId === null) return;
const copy = readState<BermSpan[]>("berm", projectId, routeId);
const next = bermSpansFromStructures(structures);
if (Array.isArray(copy) && JSON.stringify(copy) === JSON.stringify(next)) return;
writeBermSpans(projectId, routeId, next);
void Promise.all([import("./design_pipeline_cross"), import("./design_pipeline_page")])
.then(([cross, page]) => {
cross.forceCross();
page.pipelineCross(projectId);
})
.catch(() => undefined);
}
function paint(force = false): void {
const to = profile();
if (!to) return;
@@ -179,13 +205,20 @@ export function createFacilityLane(
stored = next;
},
set(next, carryEdits = true) {
if (next.structures) structures = next.structures;
if (next.structures) {
structures = next.structures;
structuresKnown = true;
}
if (next.pipes) reported = [...next.pipes];
refresh(carryEdits);
if (next.structures) run(syncBerm);
},
follow() {
structures = store.get("structures") ?? stored;
const drafted = store.get("structures");
structures = drafted ?? stored ?? [];
structuresKnown ||= drafted !== null || stored !== null;
refresh(false);
run(syncBerm);
},
setIntervalM(next) {
if (next > 0 && next !== intervalM) {