Stream long G-code execution history with scrollable panes

This commit is contained in:
2026-08-29 15:52:06 +08:00
parent 9cd70990e9
commit dfe657e736
4 changed files with 23 additions and 12 deletions

View File

@@ -75,6 +75,7 @@ export class WasmProgramRuntime {
this.path = null;
this.subroutines = [];
this.executionSource = "";
this.executionLines = [];
this.rapidVelocity = 35;
if (!this.available || typeof core?._malloc !== "function") return;
this.pointer = core._malloc(call(core, "sim_program_size", "number", [], []));
@@ -106,6 +107,7 @@ export class WasmProgramRuntime {
this.path = path;
this.subroutines = [];
this.executionSource = source;
this.executionLines = source.split(/\r?\n/);
return { status: "verified", program: this.snapshot() };
} finally { this.core._free(pointer); }
}
@@ -167,7 +169,10 @@ export class WasmProgramRuntime {
if (code !== 0) return { status: "error", code: `wasm_program_add_subroutine_${code}`, result: code };
this.subroutines.push({ name: String(name ?? "subroutine"), source });
if (this.executionSource && !this.executionSource.endsWith("\n")) this.executionSource += "\n";
if (this.executionLines.length && this.executionLines.at(-1) !== "") this.executionLines.push("");
this.executionSource += source;
if (this.executionLines.length && this.executionLines.at(-1) === "") this.executionLines.pop();
this.executionLines.push(...source.split(/\r?\n/));
return { status: "verified", command: "sim_program_add_subroutine", name: String(name ?? "subroutine") };
} finally { this.core._free(pointer); }
}
@@ -261,11 +266,10 @@ export class WasmProgramRuntime {
const state = JSON.parse(readString(this.core, buffer, required));
const hash = call(this.core, "sim_program_state_hash", "number", ["number"], [this.pointer]);
const programStatus = { 0: "idle", 1: "loaded", 2: "running", 3: "paused", 4: "completed", 5: "aborted", 6: "fault" }[state.status] ?? "idle";
const executionLines = this.executionSource ? this.executionSource.split(/\r?\n/) : [];
const executionLineText = state.current_line > 0 ? (executionLines[state.current_line - 1] ?? "").trim() : "";
const executionLineText = state.current_line > 0 ? (this.executionLines[state.current_line - 1] ?? "").trim() : "";
return { schema: SCHEMA, source: "linuxcnc-wasm-sim_program", ...state, active_gcodes: activeGcodes(state), loaded: state.status !== 0, line: state.current_line, currentLine: state.current_line, execution_line: state.current_line, execution_line_text: executionLineText, program_status: programStatus, path: this.path, subroutines: this.subroutines.map((subroutine) => subroutine.name), state_hash: `fnv1a64:${BigInt.asUintN(64, BigInt(hash >>> 0)).toString(16).padStart(16, "0")}`, source_hash: this.source ? fnv1a64(this.source) : null };
} finally { this.core._free(buffer); }
}
destroy() { for (const pointer of [this.pointer, this.motionPointer, this.samplePointer, this.samplePosePointer]) if (pointer && typeof this.core?._free === "function") this.core._free(pointer); this.pointer = this.motionPointer = this.samplePointer = this.samplePosePointer = 0; this.executionSource = ""; }
destroy() { for (const pointer of [this.pointer, this.motionPointer, this.samplePointer, this.samplePosePointer]) if (pointer && typeof this.core?._free === "function") this.core._free(pointer); this.pointer = this.motionPointer = this.samplePointer = this.samplePosePointer = 0; this.executionSource = ""; this.executionLines = []; }
}