openscad-playground/src/actions.ts

109 lines
3.4 KiB
TypeScript
Raw Normal View History

// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
2023-03-26 07:48:04 +01:00
import { getParentDir } from './filesystem';
import { spawnOpenSCAD } from "./openscad-runner";
import { processMergedOutputs } from "./output-parser";
import { AbortablePromise, turnIntoDelayableExecution } from './utils';
const syntaxDelay = 300;
type SyntaxCheckOutput = {logText: string, markers: monaco.editor.IMarkerData[]};
export const checkSyntax =
2023-03-26 07:48:04 +01:00
turnIntoDelayableExecution(syntaxDelay, (source: string, sourcePath: string) => {
// const timestamp = Date.now();
source = '$preview=true;\n' + source;
const job = spawnOpenSCAD({
2023-03-26 07:48:04 +01:00
workingDir: getParentDir(sourcePath),
inputs: [[sourcePath, source + '\n']],
args: [sourcePath, "-o", "out.ast"],
});
return AbortablePromise<SyntaxCheckOutput>((res, rej) => {
(async () => {
try {
const result = await job;
// console.log(result);
2023-03-26 07:48:04 +01:00
res(processMergedOutputs(result.mergedOutputs, {shiftSourceLines: {[sourcePath]: 1}}));
} catch (e) {
console.error(e);
rej(e);
}
})()
return () => job.kill();
});
});
var renderDelay = 1000;
2023-03-25 20:41:16 +00:00
export type RenderOutput = {stlFile: File, logText: string, markers: monaco.editor.IMarkerData[], elapsedMillis: number}
export type RenderArgs = {
source: string,
2023-03-26 07:48:04 +01:00
sourcePath: string,
features?: string[],
extraArgs?: string[],
isPreview: boolean
}
export const render =
2023-03-25 20:41:16 +00:00
turnIntoDelayableExecution(renderDelay, (params: RenderArgs) => {
const args = [
2023-03-26 07:48:04 +01:00
params.sourcePath,
2023-03-25 20:41:16 +00:00
"-o", "out.stl",
"--export-format=binstl",
...(params.features ?? []).map(f => `--enable=${f}`),
...(params.extraArgs ?? [])
]
const prefixLines: string[] = [];
if (params.isPreview) {
prefixLines.push('$preview=true;');
}
const source = [...prefixLines, params.source].join('\n');
const job = spawnOpenSCAD({
// wasmMemory,
2023-03-26 07:48:04 +01:00
workingDir: getParentDir(params.sourcePath),
inputs: [[params.sourcePath, source]],
2023-03-25 20:41:16 +00:00
args,
outputPaths: ['out.stl']
});
return AbortablePromise<RenderOutput>((resolve, reject) => {
(async () => {
try {
const result = await job;
console.log(result);
const {logText, markers} = processMergedOutputs(result.mergedOutputs, {
2023-03-26 07:48:04 +01:00
shiftSourceLines: {[params.sourcePath]: prefixLines.length}
});
if (result.error) {
reject(result.error);
}
const [output] = result.outputs ?? [];
2023-03-26 07:48:04 +01:00
if (!output) {
reject(new Error('No output from runner!'));
return;
}
const [filePath, content] = output;
const filePathFragments = filePath.split('/');
const fileName = filePathFragments[filePathFragments.length - 1];
// TODO: have the runner accept and return files.
const blob = new Blob([content], { type: "application/octet-stream" });
// console.log(new TextDecoder().decode(content));
const stlFile = new File([blob], fileName);
resolve({stlFile, logText, markers, elapsedMillis: result.elapsedMillis});
} catch (e) {
console.error(e);
reject(e);
}
})();
return () => job.kill()
});
});