Lock AXIS panel contract to source behavior

This commit is contained in:
2026-09-07 18:35:05 +08:00
parent f94f9b357e
commit 845075f4a3
7 changed files with 361 additions and 175 deletions

View File

@@ -175,7 +175,7 @@ export class SimSession {
const task = statePayload.task ?? this.task.export();
// The loaded toolpath is immutable during execution. Avoid cloning all
// WASM pose samples into every 10 ms step response; the frontend retains
// the canonical path from PROGRAM_LOAD/PROGRAM_RESTART.
// the canonical path published by the latest program transaction.
const xyzacProgramActive = Boolean(this.xyzacProgram);
const lightweightXyzacStep = input.kind === "SIM_STEP" && xyzacProgramActive;
const traceOnlyStep = lightweightXyzacStep && input.payload?.trace_only === true;
@@ -1997,7 +1997,6 @@ export class SimSession {
case "PROGRAM_LOAD": {
if (["RUNNING", "PAUSED"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "program_load_while_active"), "failed");
const source = input.payload?.source ?? input.payload?.text ?? input.payload?.program_source;
this.livePathEpoch += 1;
const savedMode = this.task.state.mode;
const restoreMode = () => {
if (savedMode !== "MANUAL" && this.task.state.mode !== savedMode) this.task.setMode(savedMode);
@@ -2077,12 +2076,11 @@ export class SimSession {
if (this.xyzacProgram) {
const previousProgramStatus = this.xyzacProgram.snapshot().program_status;
const result = this.xyzacProgram.start();
if (result.status === "verified") { this.livePathEpoch += 1; this.wasmMotion.setPaused(false); this.task.setMode("AUTO"); if (this.task.state.state === "STOPPED") this.task.recover(); this.task.transition("RUNNING"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("running", program.execution_source_line ?? program.current_line); }
if (result.status === "verified") { this.wasmMotion.setPaused(false); this.task.setMode("AUTO"); if (this.task.state.state === "STOPPED") this.task.recover(); this.task.transition("RUNNING"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("running", program.execution_source_line ?? program.current_line); }
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, reopened_taskfile: ["completed", "aborted"].includes(previousProgramStatus), start_line: 0, program: this.xyzacProgram.snapshot(), task: this.task.export(), wasm_motion: this.wasmMotion.read(), motion: this.wasmMotionProjection(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
}
const result = this.program.start();
if (result.status === "verified") {
this.livePathEpoch += 1;
this.task.setMode("AUTO");
if (this.task.state.state === "STOPPED") this.task.recover();
if (this.motionAuthority === "wasm") this.wasmMotion.setPaused(false);
@@ -2182,12 +2180,11 @@ export class SimSession {
this.xyzacDeferredPhysicalPoseApplied = false;
this.xyzacAppendDeferredOnActive = false;
const result = this.resetXyzacProgramToLoaded();
if (result.status === "verified") { this.livePathEpoch += 1; this.wasmMotion.abort(); this.wasmMotion.setPaused(false); this.task.recover(); this.task.setMode("AUTO"); this.task.setProgram("loaded", 0); }
if (result.status === "verified") { this.wasmMotion.abort(); this.wasmMotion.setPaused(false); this.task.recover(); this.task.setMode("AUTO"); this.task.setProgram("loaded", 0); }
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
}
const result = this.program.restart();
if (result.status === "verified") {
this.livePathEpoch += 1;
if (["ESTOP", "FAULT"].includes(this.task.state.state)) return finish(this.error(input, "task_state", "program_restart_faulted"), "failed");
if (["RUNNING", "PAUSED"].includes(this.task.state.state)) this.task.transition("STOPPED");
if (this.task.state.state === "STOPPED") this.task.recover();