Show live LinuxCNC G-code execution progress
This commit is contained in:
@@ -15,6 +15,16 @@ function programError(errorPrefix, result) {
|
||||
return { status: "error", code: `wasm_${errorPrefix}_${result}`, result, reason, message_key: reason, source: "linuxcnc-wasm-sim_program" };
|
||||
}
|
||||
|
||||
function modalCode(prefix, value, fallback) { return `${prefix}${Number.isFinite(Number(value)) ? Number(value) : fallback}`; }
|
||||
|
||||
function activeGcodes(state) {
|
||||
const motion = { 0: "G0", 1: "G1", 2: "G2", 3: "G3" }[state.motion_mode] ?? "G1";
|
||||
const spindle = { 3: "M3", 4: "M4", 5: "M5" }[state.spindle_mode] ?? `M${state.spindle_mode ?? 5}`;
|
||||
const feed = Number(state.feed ?? 0);
|
||||
const speed = Number(state.speed ?? 0);
|
||||
return [state.units === 20 ? "G20" : "G21", state.distance_mode === 91 ? "G91" : "G90", modalCode("G", state.plane, 17), motion, spindle, `F${Number.isFinite(feed) ? feed : 0}`, `S${Number.isFinite(speed) ? speed : 0}`].join(" ");
|
||||
}
|
||||
|
||||
function call(core, name, returnType, argTypes, args) {
|
||||
const fn = core?.[`_${name}`] ?? core?.[name];
|
||||
if (typeof fn === "function") return fn(...args);
|
||||
@@ -64,6 +74,7 @@ export class WasmProgramRuntime {
|
||||
this.source = "";
|
||||
this.path = null;
|
||||
this.subroutines = [];
|
||||
this.executionSource = "";
|
||||
this.rapidVelocity = 35;
|
||||
if (!this.available || typeof core?._malloc !== "function") return;
|
||||
this.pointer = core._malloc(call(core, "sim_program_size", "number", [], []));
|
||||
@@ -94,6 +105,7 @@ export class WasmProgramRuntime {
|
||||
this.source = source;
|
||||
this.path = path;
|
||||
this.subroutines = [];
|
||||
this.executionSource = source;
|
||||
return { status: "verified", program: this.snapshot() };
|
||||
} finally { this.core._free(pointer); }
|
||||
}
|
||||
@@ -154,6 +166,8 @@ export class WasmProgramRuntime {
|
||||
const code = call(this.core, "sim_program_add_subroutine", "number", ["number", "number", "number"], [this.pointer, pointer, bytes.byteLength]);
|
||||
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";
|
||||
this.executionSource += source;
|
||||
return { status: "verified", command: "sim_program_add_subroutine", name: String(name ?? "subroutine") };
|
||||
} finally { this.core._free(pointer); }
|
||||
}
|
||||
@@ -247,9 +261,11 @@ 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";
|
||||
return { schema: SCHEMA, source: "linuxcnc-wasm-sim_program", ...state, loaded: state.status !== 0, line: state.current_line, currentLine: state.current_line, 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 };
|
||||
const executionLines = this.executionSource ? this.executionSource.split(/\r?\n/) : [];
|
||||
const executionLineText = state.current_line > 0 ? (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; }
|
||||
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 = ""; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user