继续实现仿真测试程序

结论:真实浏览器仿真页面新增多测试程序选择和运行能力,覆盖直线、Z 轴轮廓、增量、圆弧和 G81 钻孔,并接入 Node、browser 与 release gate 验证。
This commit is contained in:
2026-06-16 21:13:09 +08:00
parent 24e1fc18b1
commit ddd5b78999
10 changed files with 461 additions and 41 deletions

View File

@@ -35,7 +35,7 @@
background: var(--surface);
padding: 14px 20px;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
grid-template-columns: minmax(0, 1fr) minmax(240px, auto) auto;
gap: 16px;
align-items: center;
}
@@ -63,6 +63,38 @@
color: var(--green);
font-weight: 700;
}
.program-controls {
display: flex;
gap: 8px;
align-items: center;
justify-content: end;
min-width: 0;
}
select, button {
border: 1px solid var(--line);
border-radius: 6px;
background: #fbfcfd;
color: var(--text);
font: 13px/1.2 "Segoe UI", sans-serif;
min-height: 32px;
}
select {
min-width: 220px;
max-width: 320px;
padding: 5px 8px;
}
button {
padding: 6px 12px;
font-weight: 650;
cursor: pointer;
}
button:hover {
border-color: var(--blue);
}
button:disabled {
cursor: wait;
opacity: 0.6;
}
.workspace {
display: grid;
grid-template-columns: minmax(280px, 0.75fr) minmax(420px, 1.35fr) minmax(300px, 0.9fr);
@@ -238,6 +270,8 @@
}
@media (max-width: 560px) {
header { grid-template-columns: 1fr; }
.program-controls { justify-content: stretch; }
.program-controls select { min-width: 0; width: 100%; }
.status-strip { justify-content: start; }
.axis-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
dl { grid-template-columns: 1fr; }
@@ -248,6 +282,10 @@
<main>
<header>
<h1>LinuxCNC Browser Simulation</h1>
<div class="program-controls">
<select data-program-selector aria-label="Simulation test program"></select>
<button type="button" data-run-program>Run</button>
</div>
<div class="status-strip">
<span class="badge">Simulation <strong data-simulation-status>loading</strong></span>
<span class="badge" data-runtime-status>LinuxCNC interpreter WASM</span>
@@ -257,7 +295,7 @@
<section aria-label="G-code program">
<div class="section-head">
<h2>Program</h2>
<p class="hint">Executed through the LinuxCNC-backed WASM interpreter.</p>
<p class="hint" data-selected-program>Executed through the LinuxCNC-backed WASM interpreter.</p>
</div>
<div class="program-lines" data-program-lines></div>
</section>
@@ -319,14 +357,51 @@
</div>
</main>
<script type="module">
import { runRealBrowserSimulation } from "./simulation-app.js";
import {
DEFAULT_SIMULATION_PROGRAM_ID,
getSimulationTestPrograms,
runRealBrowserSimulation,
} from "./simulation-app.js";
const runButton = document.querySelector("[data-run-program]");
const programSelector = document.querySelector("[data-program-selector]");
async function runSelectedProgram(programId = programSelector?.value ?? DEFAULT_SIMULATION_PROGRAM_ID) {
document.body.dataset.simulationReady = "false";
document.querySelector("[data-simulation-status]").textContent = "running";
if (runButton) {
runButton.disabled = true;
}
try {
const state = await runRealBrowserSimulation({ documentRef: document, programId });
window.linuxCncRealSimulationState = state;
return state;
} finally {
if (runButton) {
runButton.disabled = false;
}
}
}
try {
const state = await runRealBrowserSimulation({ documentRef: document });
const state = await runSelectedProgram(DEFAULT_SIMULATION_PROGRAM_ID);
window.linuxCncRealSimulationState = state;
window.linuxCncRealSimulationApi = {
getState: () => window.linuxCncRealSimulationState,
getPrograms: getSimulationTestPrograms,
runProgramById: async (programId) => {
const nextState = await runSelectedProgram(programId);
window.linuxCncRealSimulationState = nextState;
return nextState;
},
};
runButton?.addEventListener("click", () => {
window.linuxCncRealSimulationApi.runProgramById(programSelector.value).catch((error) => {
document.body.dataset.simulationReady = "false";
document.querySelector("[data-simulation-status]").textContent = "failed";
document.querySelector("[data-canonical-output]").textContent = error?.stack ?? error?.message ?? String(error);
});
});
} catch (error) {
document.body.dataset.simulationReady = "false";
document.querySelector("[data-simulation-status]").textContent = "failed";