支持真实G代码程序执行
结论:AXIS 风格浏览器仿真页面新增 Open Program、runProgramText 和 loadProgramFile,支持用户提供的 G-code 文本/文件通过 LinuxCNC WASM 执行并参与回放。
This commit is contained in:
@@ -501,6 +501,14 @@
|
||||
.axis-statusbar { grid-template-columns: 1fr; }
|
||||
dl { grid-template-columns: 1fr; }
|
||||
}
|
||||
.hidden-file-input {
|
||||
position: absolute;
|
||||
inline-size: 1px;
|
||||
block-size: 1px;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-simulation-ready="false">
|
||||
@@ -510,6 +518,7 @@
|
||||
<h1>axis.ngc - AXIS 2.9.8 on LinuxCNC-BROWSER-SIM</h1>
|
||||
<div class="window-controls" aria-hidden="true"><span>⌃</span><span>−</span><span>□</span><span>×</span></div>
|
||||
</header>
|
||||
<input class="hidden-file-input" type="file" accept=".ngc,.nc,.tap,.gcode,.txt" data-open-program-file>
|
||||
<nav class="axis-menubar" data-axis-shell="menubar" aria-label="AXIS menu">
|
||||
<span>File</span>
|
||||
<span>Machine</span>
|
||||
@@ -518,7 +527,7 @@
|
||||
</nav>
|
||||
<div class="axis-toolbar" data-axis-shell="toolbar" aria-label="AXIS toolbar">
|
||||
<button type="button" class="toolbar-button" aria-label="Emergency stop">■</button>
|
||||
<button type="button" class="toolbar-button" aria-label="Open program">▣</button>
|
||||
<button type="button" class="toolbar-button" aria-label="Open program" data-open-program>Open</button>
|
||||
<button type="button" class="toolbar-button" aria-label="Reload program">↻</button>
|
||||
<div class="program-controls">
|
||||
<select data-program-selector aria-label="Simulation test program"></select>
|
||||
@@ -643,7 +652,7 @@
|
||||
</div>
|
||||
<section class="axis-gcode-pane" data-axis-shell="gcode-pane" aria-label="G-code program">
|
||||
<div class="axis-gcode-head">
|
||||
<span>Program: <span data-selected-program>Executed through the LinuxCNC-backed WASM interpreter.</span></span>
|
||||
<span>Program: <span data-selected-program>Executed through the LinuxCNC-backed WASM interpreter.</span> | Source: <span data-program-source>loading</span></span>
|
||||
<span>Active line <span data-active-line>-</span></span>
|
||||
</div>
|
||||
<div class="program-lines" data-program-lines></div>
|
||||
@@ -678,7 +687,7 @@
|
||||
</section>
|
||||
<footer class="axis-statusbar" data-axis-shell="statusbar">
|
||||
<span>ESTOP</span>
|
||||
<span>No tool</span>
|
||||
<span>No tool | <span data-program-source>loading</span></span>
|
||||
<span>Position: Relative Actual</span>
|
||||
</footer>
|
||||
</main>
|
||||
@@ -692,6 +701,8 @@
|
||||
|
||||
const runButton = document.querySelector("[data-run-program]");
|
||||
const programSelector = document.querySelector("[data-program-selector]");
|
||||
const openProgramButton = document.querySelector("[data-open-program]");
|
||||
const openProgramFile = document.querySelector("[data-open-program-file]");
|
||||
const resetButton = document.querySelector("[data-playback-reset]");
|
||||
const prevButton = document.querySelector("[data-playback-prev]");
|
||||
const playButton = document.querySelector("[data-playback-play]");
|
||||
@@ -807,6 +818,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function runProgramText(programText, metadata = {}) {
|
||||
stopPlayback();
|
||||
document.body.dataset.simulationReady = "false";
|
||||
setAllText("[data-simulation-status]", "running");
|
||||
if (runButton) {
|
||||
runButton.disabled = true;
|
||||
}
|
||||
try {
|
||||
const state = await runRealBrowserSimulation({ documentRef: document, programText });
|
||||
const label = metadata.label ?? metadata.filename ?? "Custom G-code program";
|
||||
const sourceLabel = metadata.filename ? `Loaded file: ${metadata.filename}` : (metadata.sourceLabel ?? "Custom G-code text");
|
||||
state.program = {
|
||||
id: "custom",
|
||||
label,
|
||||
category: "Custom",
|
||||
source: metadata.source ?? "custom",
|
||||
sourceLabel,
|
||||
filename: metadata.filename ?? null,
|
||||
};
|
||||
window.linuxCncRealSimulationState = state;
|
||||
document.body.dataset.simulationProgramId = "custom";
|
||||
document.body.dataset.simulationProgramSource = state.program.source;
|
||||
setAllText("[data-selected-program]", state.program.label);
|
||||
setAllText("[data-program-source]", state.program.sourceLabel);
|
||||
renderPlayback(0);
|
||||
return state;
|
||||
} finally {
|
||||
if (runButton) {
|
||||
runButton.disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function loadProgramFile(file) {
|
||||
const text = await file.text();
|
||||
return runProgramText(text, {
|
||||
filename: file.name,
|
||||
label: file.name,
|
||||
source: "file",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const state = await runSelectedProgram(DEFAULT_SIMULATION_PROGRAM_ID);
|
||||
window.linuxCncRealSimulationState = state;
|
||||
@@ -819,6 +872,8 @@
|
||||
play: startPlayback,
|
||||
pause: stopPlayback,
|
||||
finishPlayback: () => renderPlayback(currentState()?.motion.length - 1 ?? 0),
|
||||
runProgramText,
|
||||
loadProgramFile,
|
||||
runProgramById: async (programId) => {
|
||||
const nextState = await runSelectedProgram(programId);
|
||||
window.linuxCncRealSimulationState = nextState;
|
||||
@@ -832,6 +887,18 @@
|
||||
document.querySelector("[data-canonical-output]").textContent = error?.stack ?? error?.message ?? String(error);
|
||||
});
|
||||
});
|
||||
openProgramButton?.addEventListener("click", () => openProgramFile?.click());
|
||||
openProgramFile?.addEventListener("change", () => {
|
||||
const file = openProgramFile.files?.[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
window.linuxCncRealSimulationApi.loadProgramFile(file).catch((error) => {
|
||||
document.body.dataset.simulationReady = "false";
|
||||
setAllText("[data-simulation-status]", "failed");
|
||||
document.querySelector("[data-canonical-output]").textContent = error?.stack ?? error?.message ?? String(error);
|
||||
});
|
||||
});
|
||||
resetButton?.addEventListener("click", () => renderPlayback(0));
|
||||
prevButton?.addEventListener("click", () => stepPlayback(-1));
|
||||
playButton?.addEventListener("click", togglePlayback);
|
||||
|
||||
Reference in New Issue
Block a user