Files
cnc_wams/wasm-port/runtime/sdk/src/linuxcnc-interp.js
2026-06-09 06:13:28 +08:00

165 lines
4.4 KiB
JavaScript

import createLinuxCncInterpModule from "../../../build/wasm/core/linuxcnc_interp.js";
function allocCString(mod, value) {
const bytes = mod.lengthBytesUTF8(value) + 1;
const ptr = mod._malloc(bytes);
mod.stringToUTF8(value, ptr, bytes);
return ptr;
}
function ensureParentPath(mod, path) {
const parts = path.split("/").filter(Boolean);
let current = "";
for (const part of parts.slice(0, -1)) {
current += `/${part}`;
try {
mod.FS.mkdir(current);
} catch {
// Directory already exists.
}
}
}
function copyResultString(mod, resultPtr, functionName) {
if (!resultPtr) {
throw new Error(`${functionName} returned null`);
}
return mod.UTF8ToString(resultPtr);
}
function callStringResult(mod, functionName, ...values) {
const ptrs = values.map((value) => allocCString(mod, value));
let resultPtr = 0;
try {
resultPtr = mod[`_${functionName}`](...ptrs);
return copyResultString(mod, resultPtr, functionName);
} finally {
if (resultPtr) {
mod._lcinterp_free_string(resultPtr);
}
for (const ptr of ptrs) {
mod._free(ptr);
}
}
}
export async function createLinuxCncInterpSdk(moduleOptions = {}) {
const mod = await createLinuxCncInterpModule(moduleOptions);
return {
module: mod,
writeTextFile(path, text) {
ensureParentPath(mod, path);
mod.FS.writeFile(path, text, { encoding: "utf8" });
},
readTextFile(path) {
return mod.FS.readFile(path, { encoding: "utf8" });
},
runSimConfigProgram({
iniPath,
programPath,
files = [],
executionMode = "fileWithIni",
}) {
for (const file of files) {
ensureParentPath(mod, file.path);
mod.FS.writeFile(file.path, file.text, { encoding: "utf8" });
if (file.executable) {
mod.FS.chmod(file.path, 0o755);
}
}
if (executionMode === "fiveAxisRemap") {
return callStringResult(
mod,
"lcinterp_run_fiveaxis_remap_file",
programPath,
iniPath,
);
}
if (executionMode === "fileWithIni") {
return callStringResult(mod, "lcinterp_run_file_with_ini", programPath, iniPath);
}
throw new Error(`unsupported sim config execution mode: ${executionMode}`);
},
runProgram(programText) {
return callStringResult(mod, "lcinterp_run_program", programText);
},
runProgramWithIni(programText, iniPath) {
return callStringResult(mod, "lcinterp_run_program_with_ini", programText, iniPath);
},
runFile(path) {
return callStringResult(mod, "lcinterp_run_file", path);
},
runFileWithIni(path, iniPath) {
return callStringResult(mod, "lcinterp_run_file_with_ini", path, iniPath);
},
runFileWithIniContinueOnError(path, iniPath) {
return callStringResult(
mod,
"lcinterp_run_file_with_ini_continue_on_error",
path,
iniPath,
);
},
runFiveAxisRemapFile(path, iniPath) {
return callStringResult(mod, "lcinterp_run_fiveaxis_remap_file", path, iniPath);
},
runRemapFile(path, iniPath) {
return callStringResult(mod, "lcinterp_run_remap_file", path, iniPath);
},
runRemapFileContinueOnError(path, iniPath) {
return callStringResult(mod, "lcinterp_run_remap_file_continue_on_error", path, iniPath);
},
runRemapIoMdiSequence(iniPath) {
return callStringResult(mod, "lcinterp_run_remap_io_mdi_sequence", iniPath);
},
restoreParameters(path) {
return callStringResult(mod, "lcinterp_restore_parameters", path);
},
saveParameters(path, values) {
const assignments = Object.entries(values)
.map(([parameter, value]) => `${parameter} ${value}`)
.join("\n");
return callStringResult(mod, "lcinterp_save_parameters", path, assignments);
},
loadToolTable(path, options = {}) {
const functionName = options.randomToolChanger
? "lcinterp_load_tool_table_random"
: "lcinterp_load_tool_table";
return callStringResult(mod, functionName, path);
},
saveToolTable(path) {
return callStringResult(mod, "lcinterp_save_tool_table", path);
},
probeInitAndSynch() {
return callStringResult(mod, "lcinterp_probe_init_and_synch");
},
probeIndexer() {
return callStringResult(mod, "lcinterp_probe_indexer");
},
probeNamedParameters(iniPath) {
return callStringResult(mod, "lcinterp_probe_named_parameters", iniPath);
},
};
}