接上一轮,按接续文件继续执行
结论:Three.js 程序预览和刀具执行显示已收口,公网 HTTP/IP 下 Save/Restore Session 已支持 memory-fallback 降级并通过 node/browser gate。
This commit is contained in:
@@ -76,11 +76,14 @@
|
||||
if (
|
||||
canvas.dataset.threeReady !== "true" ||
|
||||
canvas.dataset.threeFrameApi !== "web-rtcp-5axis-motion-frame" ||
|
||||
canvas.dataset.threeSceneMode !== "program-preview-and-tool-execution" ||
|
||||
canvas.dataset.threeCameraControls !== "orbit-pan-zoom" ||
|
||||
Number(canvas.dataset.threePathPoints ?? 0) < 64 ||
|
||||
Number(canvas.dataset.threeSceneObjects ?? 0) < 12 ||
|
||||
Number(canvas.dataset.threeSceneObjects ?? 0) < 5 ||
|
||||
!canvas.dataset.threeToolhead ||
|
||||
!canvas.dataset.threeToolAxis ||
|
||||
!canvas.dataset.threeTcpPose
|
||||
!canvas.dataset.threeTcpPose ||
|
||||
canvas.dataset.threeToolExecutionMarker !== "true"
|
||||
) {
|
||||
throw new Error(`Three.js preview did not expose ready render state: ${JSON.stringify(canvas.dataset)}`);
|
||||
}
|
||||
@@ -269,6 +272,14 @@
|
||||
if (win.webRtcp5AxisSimulation.getState().programRuntimeFeedback?.semanticBoundary !== "linuxcnc_tp_run_cycle_feedback_without_hardware") {
|
||||
throw new Error(`initial runtime feedback did not use LinuxCNC TP sample: ${JSON.stringify(win.webRtcp5AxisSimulation.getState().programRuntimeFeedback)}`);
|
||||
}
|
||||
canvas = doc.querySelector("[data-five-axis-canvas]");
|
||||
if (
|
||||
canvas.dataset.threeProgramPreviewSource !== "linuxcnc-interpreter-wasm" ||
|
||||
Number(canvas.dataset.threePathPoints ?? 0) < win.webRtcp5AxisSimulation.getState().programExecution.summary.motionEventCount ||
|
||||
Number(canvas.dataset.threeExecutedPathPoints ?? 0) < 1
|
||||
) {
|
||||
throw new Error(`Three.js preview did not consume LinuxCNC program execution path: ${JSON.stringify(canvas.dataset)}`);
|
||||
}
|
||||
if (!doc.querySelector('[data-program-execution-source]')?.textContent.includes("linuxcnc-interpreter-wasm")) {
|
||||
throw new Error("program execution source DOM did not render interpreter source");
|
||||
}
|
||||
@@ -369,9 +380,15 @@
|
||||
if (savedSession.snapshot.format !== "web-rtcp-5axis-session-snapshot") {
|
||||
throw new Error("saveSession did not write a five-axis session snapshot");
|
||||
}
|
||||
if (!["opfs", "memory-fallback"].includes(savedSession.storageMode)) {
|
||||
throw new Error(`saveSession used unexpected storage mode: ${savedSession.storageMode}`);
|
||||
}
|
||||
if (!doc.querySelector('[data-session-persistence="status"]')?.textContent.includes("saved")) {
|
||||
throw new Error("session save status did not render");
|
||||
}
|
||||
if (!doc.querySelector('[data-session-persistence="status"]')?.textContent.includes(savedSession.storageMode)) {
|
||||
throw new Error("session save status did not render storage mode");
|
||||
}
|
||||
if (doc.querySelector('[data-active-program-line]')?.textContent !== "Current line 2") {
|
||||
throw new Error("loaded program did not render first LinuxCNC motion line");
|
||||
}
|
||||
@@ -393,6 +410,13 @@
|
||||
if (Number(doc.querySelector(".gcode-row.active")?.dataset.programLine || 0) < 2) {
|
||||
throw new Error("RUN did not highlight a LinuxCNC task/HAL motion line");
|
||||
}
|
||||
canvas = doc.querySelector("[data-five-axis-canvas]");
|
||||
if (
|
||||
Number(canvas.dataset.threeExecutedPathPoints ?? 0) < 1 ||
|
||||
canvas.dataset.threeToolExecutionMarker !== "true"
|
||||
) {
|
||||
throw new Error(`Three.js preview did not display tool execution progress: ${JSON.stringify(canvas.dataset)}`);
|
||||
}
|
||||
const taskHalRunState = win.webRtcp5AxisSimulation.getState();
|
||||
if (taskHalRunState.fullExecutionBoundary?.semanticBoundary !== "linuxcnc_task_motion_hal_wasm_simulation_runtime") {
|
||||
throw new Error(`full execution boundary did not promote task/HAL simulation runtime: ${JSON.stringify(taskHalRunState.fullExecutionBoundary)}`);
|
||||
@@ -504,6 +528,23 @@
|
||||
if (!doc.querySelector('[data-session-persistence="status"]')?.textContent.includes("restored")) {
|
||||
throw new Error("session restore status did not render");
|
||||
}
|
||||
if (!doc.querySelector('[data-session-persistence="status"]')?.textContent.includes(savedSession.storageMode)) {
|
||||
throw new Error("session restore status did not preserve storage mode");
|
||||
}
|
||||
doc.querySelector('[data-action="SAVE_SESSION"]').click();
|
||||
await wait(120);
|
||||
const uiSavedSession = win.webRtcp5AxisSimulation.getState().sessionPersistence;
|
||||
if (uiSavedSession.status !== "saved" || !["opfs", "memory-fallback"].includes(uiSavedSession.storageMode)) {
|
||||
throw new Error(`UI Save Session did not use a supported storage mode: ${JSON.stringify(uiSavedSession)}`);
|
||||
}
|
||||
doc.querySelector('[data-action="JOG_X_POS"]').click();
|
||||
await wait(50);
|
||||
doc.querySelector('[data-action="RESTORE_SESSION"]').click();
|
||||
await wait(180);
|
||||
const uiRestoredSession = win.webRtcp5AxisSimulation.getState().sessionPersistence;
|
||||
if (uiRestoredSession.status !== "restored" || uiRestoredSession.storageMode !== uiSavedSession.storageMode) {
|
||||
throw new Error(`UI Restore Session did not restore from default storage fallback: ${JSON.stringify(uiRestoredSession)}`);
|
||||
}
|
||||
if (win.webRtcp5AxisSimulation.getState().machine.allHomed !== true) {
|
||||
doc.querySelector('[data-action="mode-manual"]').click();
|
||||
await wait(50);
|
||||
@@ -569,11 +610,46 @@
|
||||
if (win.webRtcp5AxisSimulation.getState().preview.selectedView !== "x") {
|
||||
throw new Error("preview view button did not update state");
|
||||
}
|
||||
canvas = doc.querySelector("[data-five-axis-canvas]");
|
||||
canvas.dispatchEvent(new WheelEvent("wheel", { deltaY: -120, bubbles: true, cancelable: true }));
|
||||
canvas.dispatchEvent(new PointerEvent("pointerdown", {
|
||||
pointerId: 1,
|
||||
clientX: 180,
|
||||
clientY: 120,
|
||||
button: 0,
|
||||
bubbles: true,
|
||||
}));
|
||||
canvas.dispatchEvent(new PointerEvent("pointermove", {
|
||||
pointerId: 1,
|
||||
clientX: 220,
|
||||
clientY: 135,
|
||||
button: 0,
|
||||
bubbles: true,
|
||||
}));
|
||||
canvas.dispatchEvent(new PointerEvent("pointerup", {
|
||||
pointerId: 1,
|
||||
clientX: 220,
|
||||
clientY: 135,
|
||||
button: 0,
|
||||
bubbles: true,
|
||||
}));
|
||||
await wait(50);
|
||||
if (canvas.dataset.threeCameraControls !== "orbit-pan-zoom") {
|
||||
throw new Error("Three.js preview did not expose orbit/pan/zoom controls");
|
||||
}
|
||||
assertCanvasNonblank(canvas, "interactive Three.js preview");
|
||||
doc.querySelector('[data-action="clear-preview"]').click();
|
||||
await wait(50);
|
||||
if (win.webRtcp5AxisSimulation.getState().preview.pathPoints !== 0) {
|
||||
throw new Error("clear preview button did not update path points");
|
||||
}
|
||||
canvas = doc.querySelector("[data-five-axis-canvas]");
|
||||
if (Number(canvas.dataset.threePathPoints ?? -1) !== 0) {
|
||||
throw new Error(`Three.js preview did not clear toolpath points: ${JSON.stringify(canvas.dataset)}`);
|
||||
}
|
||||
if (Number(canvas.dataset.threeExecutedPathPoints ?? -1) !== 0) {
|
||||
throw new Error(`Three.js preview did not clear executed toolpath points: ${JSON.stringify(canvas.dataset)}`);
|
||||
}
|
||||
doc.querySelector('[data-action="RELOAD"]').click();
|
||||
await wait(50);
|
||||
if (win.webRtcp5AxisSimulation.getState().preview.pathPoints !== 8) {
|
||||
|
||||
Reference in New Issue
Block a user