From 0bc5606638a2c2cf30f1195039c9785479089c79 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 4 Oct 2026 22:44:36 +0900 Subject: [PATCH] =?UTF-8?q?feat(M02):=20CAD=20=ED=91=9C=20=EB=86=93?= =?UTF-8?q?=EA=B8=B0=20=C2=B7=20=EC=B9=B8=20=EA=B0=88=EA=B8=B0=20=ED=98=B8?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=ED=95=A8=EC=88=98=20=E2=80=94=20cad=5Fhos?= =?UTF-8?q?t=20placeTable=20=C2=B7=20updateTable=20=C2=B7=20=EB=8F=84?= =?UTF-8?q?=EB=A9=B4=20=EC=86=90=EC=9E=A1=EC=9D=B4=20(41-2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cad_host: placeTable(entity, link) · updateTable(link, cells) → 바꾼 표 수 · 도면이 열리기 전이면 열린 뒤 보냄(싣기가 덮지 않게) · 5 초 넘으면 실패 - M02_MasterTemplete_Drawing: DrawingTemplateHandle 에 같은 함수 둘 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s --- .../M02_MasterTemplete_Drawing.ts | 5 ++ ui_template/cad_host/cad_host.ts | 51 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/M02_MasterTemplete/M02_MasterTemplete_Drawing.ts b/M02_MasterTemplete/M02_MasterTemplete_Drawing.ts index 7650e1d2a..8aa61bc40 100644 --- a/M02_MasterTemplete/M02_MasterTemplete_Drawing.ts +++ b/M02_MasterTemplete/M02_MasterTemplete_Drawing.ts @@ -77,6 +77,9 @@ function migrateOldRecovery(options: DrawingTemplateOptions, scope: string): voi export interface DrawingTemplateHandle { getDoc: () => Promise; + /** 표 놓기 · 칸 갈기(41장) — `cad_host` 그대로 */ + placeTable: (entity: Record, link: string) => void; + updateTable: (link: string, cells: unknown[][]) => Promise; destroy: () => void; } @@ -277,6 +280,8 @@ export function mountDrawingTemplate( return { getDoc, + placeTable: cad.placeTable, + updateTable: cad.updateTable, destroy: () => { areaModal?.close(); cad.destroy(); diff --git a/ui_template/cad_host/cad_host.ts b/ui_template/cad_host/cad_host.ts index 88c27c69e..db2f74a87 100644 --- a/ui_template/cad_host/cad_host.ts +++ b/ui_template/cad_host/cad_host.ts @@ -28,6 +28,10 @@ const CAD_HOST_SAVE_MESSAGE = "aislo:b08:host-save"; * CAD 안 react-toastify는 모양·자리가 달라 한 화면에 두 종류가 섞여 보였다. */ const CAD_TOAST_MESSAGE = "aislo:b08:toast"; const CAD_TOAST_ACTION_MESSAGE = "aislo:b08:toast-action"; +/** 표(M02 41장) — 짝 = CAD `integration/aislo-table-bridge.ts` */ +const CAD_PLACE_TABLE_MESSAGE = "aislo:b08:place-table"; +const CAD_UPDATE_TABLE_MESSAGE = "aislo:b08:update-table"; +const CAD_TABLE_UPDATED_MESSAGE = "aislo:b08:table-updated"; /** CAD 가 주고받는 도면 JSON — 도형·층 밖의 칸은 페이지마다 다르다. */ export interface CadHostDrawing { @@ -93,6 +97,11 @@ export interface CadHost { ) => void; /** CAD 의 지금 편집본을 받는다. */ requestSave: () => Promise>; + /** 표 놓기(41장) — `entity` = 표 JSON(TableEntity 꼴) · CAD 가 `style.연결 = link` 로 커서에 붙여 놓게 함. + * 도면이 아직 안 열렸으면 열린 뒤 보냄 · 놓기는 사용자가 누를 때 · 저장은 [저장]. */ + placeTable: (entity: Record, link: string) => void; + /** 표 칸 갈기(41장) — `style.연결 === link` 인 표의 칸만(자리 · 크기 그대로) · 돌려받는 수 = 바꾼 표 수(0 = 없음). */ + updateTable: (link: string, cells: unknown[][]) => Promise; /** 메시지 듣기를 멈춘다 — 페이지를 떠날 때. */ destroy: () => void; } @@ -177,6 +186,35 @@ export function createCadHost[] = []; + const postAfterLoad = (message: Record): void => { + if (drawingLoaded) post(message); + else afterLoad.push(message); + }; + const tableWaits = new Map void)[]>(); + + const placeTable: CadHost["placeTable"] = (entity, link) => + postAfterLoad({ type: CAD_PLACE_TABLE_MESSAGE, entity, link }); + + const updateTable: CadHost["updateTable"] = (link, cells) => + new Promise((resolve, reject) => { + const waits = tableWaits.get(link) ?? []; + waits.push(resolve); + tableWaits.set(link, waits); + postAfterLoad({ type: CAD_UPDATE_TABLE_MESSAGE, link, cells }); + window.setTimeout(() => { + const left = tableWaits.get(link) ?? []; + if (!left.includes(resolve)) return; + tableWaits.set( + link, + left.filter((one) => one !== resolve), + ); + reject(new Error("CAD 표 갈기 응답 시간이 초과되었습니다.")); + }, 5000); + }); + const load: CadHost["load"] = ( drawing, meta, @@ -185,6 +223,7 @@ export function createCadHost { pendingLoad = { drawing, meta, frameEdit, frameFields, extra }; + drawingLoaded = false; // 새로 싣는 중 — 표는 열린 뒤에 if (!cadReady) return; post({ type: CAD_LOAD_MESSAGE, drawing, meta, frameEdit, frameFields, ...extra }); pendingLoad = undefined; @@ -215,6 +254,8 @@ export function createCadHost { stopLoadWatchdog(); window.removeEventListener("message", onMessage);