From ccd6b67e35152295a1599662adef049bb937a0ef Mon Sep 17 00:00:00 2001 From: wangdequan Date: Sun, 14 Jun 2026 17:35:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E8=BF=9B=20INI=20=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=91=98=E8=A6=81=E7=BB=93=E6=9E=9C=E8=AE=A1?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- text10.txt | 63 ++++++++++++++++++++ wasm-port/runtime/ui/ini-panel/app.js | 28 ++++++--- wasm-port/tests/browser/ini_panel_smoke.html | 32 ++++++++++ 3 files changed, 116 insertions(+), 7 deletions(-) diff --git a/text10.txt b/text10.txt index 752ee90..f865f27 100644 --- a/text10.txt +++ b/text10.txt @@ -1095,3 +1095,66 @@ host_wasm_opfs_browser_smokes=ok `runStatus` 和 `iniWasmPath`,方便 UI/API 判断运行是否真的产生 LinuxCNC canonical output; 仍只统计 LinuxCNC-owned runtime 输出,不解析或改写 G-code、tool、parameter、planner 等 CNC 语义。 + +十五、2026-06-14 继续执行记录:INI panel run summary result counts + +本轮继续沿 OPFS/session/UI boundary 推进,把 `Run G-code` 的机器可读 summary 扩展为 +轻量 runtime result 摘要,方便 UI/API 判断一次运行是否确实产生 LinuxCNC canonical output。 + +完成内容: + +- 在 `wasm-port/runtime/ui/ini-panel/app.js` 新增 `countCanonicalEvents(resultText)`; +- `window.linuxCncIniPanelLastRunSummary` 现在额外包含: + - `runStatus`; + - `iniWasmPath`; + - `canonicalEventCount`; + - `motionSnapshotCount`; +- `Run G-code` 成功路径先复用 LinuxCNC interpreter WASM 输出生成: + - trimmed result; + - canonical event count; + - motion snapshots; +- `playRunMotion(...)` 支持接收已解析的 motion snapshots,避免重复解析同一份结果; +- fallback run 与 snapshot run 的 browser smoke 均验证: + - `runStatus: "ok"`; + - `iniWasmPath: "/work/session-machine.ini"`; + - `canonicalEventCount: 2`; + - `motionSnapshotCount: 2`; +- 未改变 OPFS path model、snapshot envelope、G-code 文本、interpreter run API、 + canonical-event 文本输出、motion playback 语义或 LinuxCNC-owned runtime semantics。 + +验证已通过: + +```bash +git diff --check +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh +wasm-port/tests/opfs/node/verify_file_service.sh +wasm-port/tools/verify_vendor_sync.sh +wasm-port/tools/verify_no_standalone_cnc_semantics.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +关键输出: + +```text +browser_ini_opfs_smoke=ok +opfs_file_service_node_smoke=ok +vendor sync up to date +standalone CNC semantics guard complete +interp_wasm_node_smoke=ok +sim_configs_wasm_node_inventory_executed=28 +sim_configs_wasm_node_inventory_passed=28 +sim_configs_wasm_node_inventory_skipped=131 +sim_configs_wasm_node_inventory_unexpected_fail=0 +browser_interp_smoke=ok +host_wasm_opfs_browser_smokes=ok +``` + +下一步建议: + +继续沿 OPFS/session/UI boundary 推进。优先把 `linuxCncIniPanelLastRunSummary` 的生成 +收敛为一个可导出的纯 helper,例如 `createRunSummary(program, runtime, snapshot)`, +并补 Node/browser 侧轻量测试,方便后续 SDK/API 或其他 UI panel 复用;保持 helper 只聚合 +host/runtime 边界数据,不解析 G-code、tool、parameter、planner 等 CNC 语义。 diff --git a/wasm-port/runtime/ui/ini-panel/app.js b/wasm-port/runtime/ui/ini-panel/app.js index 71af5f5..e2f5041 100644 --- a/wasm-port/runtime/ui/ini-panel/app.js +++ b/wasm-port/runtime/ui/ini-panel/app.js @@ -282,9 +282,8 @@ function showRunSnapshot(snapshot, index, total) { ); } -function playRunMotion(resultText, programText) { +function playRunMotion(resultText, programText, snapshots = parseRunMotion(resultText, programText)) { clearRunPlayback(); - const snapshots = parseRunMotion(resultText, programText); if (snapshots.length === 0) { setRunMonitor(100, "100%", {}, "complete; no axis motion"); return; @@ -303,6 +302,10 @@ function playRunMotion(resultText, programText) { }, 220); } +function countCanonicalEvents(resultText) { + return resultText.split("\n").filter((line) => line.startsWith("canon_event=")).length; +} + function requireIniSdk() { if (!iniSdk) { throw new Error("INI WASM module is not ready yet."); @@ -364,15 +367,19 @@ function clearLastRunSummary() { setField("runWasmPath", "-"); } -function setLastRunSummary(program, snapshot = restoredSessionSnapshot) { +function setLastRunSummary(program, runtime = {}, snapshot = restoredSessionSnapshot) { const snapshotLabel = snapshot ? sessionSnapshotLabel(snapshot.sessionId) : null; const metadata = snapshot?.metadata ?? {}; const summary = { + runStatus: runtime.runStatus ?? "ok", programSource: program.source, snapshotLabel, workflow: metadata.workflow ?? null, programOpfsPath: program.opfsPath, programWasmPath: program.wasmPath, + iniWasmPath: runtime.iniWasmPath ?? null, + canonicalEventCount: runtime.canonicalEventCount ?? 0, + motionSnapshotCount: runtime.motionSnapshotCount ?? 0, }; window.linuxCncIniPanelLastRunSummary = summary; setField("runSource", summary.programSource); @@ -664,17 +671,24 @@ document.getElementById("run-gcode").addEventListener("click", async () => { setRunMonitor(5, "running", {}, "running"); await nextFrame(); const result = interp.runFileWithIni(program.wasmPath, loadedSession.ini.wasmPath); + const trimmedResult = result.trim(); + const motionSnapshots = parseRunMotion(trimmedResult, program.text); setField("sessionGcode", program.opfsPath); setField("runStatus", "ok"); - setLastRunSummary(program); - setCanonicalEvents(result.trim()); - playRunMotion(result.trim(), program.text); + setLastRunSummary(program, { + runStatus: "ok", + iniWasmPath: loadedSession.ini.wasmPath, + canonicalEventCount: countCanonicalEvents(trimmedResult), + motionSnapshotCount: motionSnapshots.length, + }); + setCanonicalEvents(trimmedResult); + playRunMotion(trimmedResult, program.text, motionSnapshots); setLog( [ "Ran G-code through LinuxCNC interpreter WASM.", ...runSessionContextLogLines(program), `INI: ${loadedSession.ini.wasmPath}`, - result.trim(), + trimmedResult, ].join("\n"), ); } catch (error) { diff --git a/wasm-port/tests/browser/ini_panel_smoke.html b/wasm-port/tests/browser/ini_panel_smoke.html index b348132..a6ea383 100644 --- a/wasm-port/tests/browser/ini_panel_smoke.html +++ b/wasm-port/tests/browser/ini_panel_smoke.html @@ -437,6 +437,7 @@ TOOL_TABLE = browser-tool.tbl "UI fallback run WASM field", ); const fallbackRunSummary = uiDocument.defaultView.linuxCncIniPanelLastRunSummary; + assertEqual(fallbackRunSummary.runStatus, "ok", "UI fallback run summary status"); assertEqual(fallbackRunSummary.programSource, "default", "UI fallback run summary source"); assertEqual(fallbackRunSummary.snapshotLabel, null, "UI fallback run summary snapshot"); assertEqual(fallbackRunSummary.workflow, null, "UI fallback run summary workflow"); @@ -450,6 +451,21 @@ TOOL_TABLE = browser-tool.tbl "/work/ui-session.ngc", "UI fallback run summary WASM path", ); + assertEqual( + fallbackRunSummary.iniWasmPath, + "/work/session-machine.ini", + "UI fallback run summary INI WASM path", + ); + assertEqual( + fallbackRunSummary.canonicalEventCount, + 2, + "UI fallback run summary canonical event count", + ); + assertEqual( + fallbackRunSummary.motionSnapshotCount, + 2, + "UI fallback run summary motion snapshot count", + ); uiDocument.getElementById("save-session-snapshot").click(); await waitFor( () => uiDocument.getElementById("log")?.textContent.includes("Saved machine session snapshot"), @@ -607,6 +623,7 @@ TOOL_TABLE = browser-tool.tbl "UI snapshot run WASM field", ); const snapshotRunSummary = uiDocument.defaultView.linuxCncIniPanelLastRunSummary; + assertEqual(snapshotRunSummary.runStatus, "ok", "UI snapshot run summary status"); assertEqual(snapshotRunSummary.programSource, "snapshot", "UI snapshot run summary source"); assertEqual( snapshotRunSummary.snapshotLabel, @@ -628,6 +645,21 @@ TOOL_TABLE = browser-tool.tbl "/work/ui-session.ngc", "UI snapshot run summary WASM path", ); + assertEqual( + snapshotRunSummary.iniWasmPath, + "/work/session-machine.ini", + "UI snapshot run summary INI WASM path", + ); + assertEqual( + snapshotRunSummary.canonicalEventCount, + 2, + "UI snapshot run summary canonical event count", + ); + assertEqual( + snapshotRunSummary.motionSnapshotCount, + 2, + "UI snapshot run summary motion snapshot count", + ); if ( !runLog.includes("canon_event=STRAIGHT_TRAVERSE") || !runLog.includes("canon_event=STRAIGHT_FEED")