Skip to content

Commit

Permalink
Add full exception mode to the studio
Browse files Browse the repository at this point in the history
  • Loading branch information
sgenoud committed Jul 6, 2024
1 parent df5b0ec commit 2e89f98
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 33 deletions.
58 changes: 52 additions & 6 deletions packages/studio/src/builder.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expose } from "comlink";
import * as replicad from "replicad";

import initOpenCascade from "./initOCSingle.js";
import initOpenCascadeWithExceptions from "./initOCWithExceptions.js";
import normalizeColor from "./utils/normalizeColor";
import { runInContext, buildModuleEvaluator } from "./vm";

Expand Down Expand Up @@ -77,9 +78,42 @@ return dp

const SHAPES_MEMORY = {};

let OC = initOpenCascade().then((oc) => {
return oc;
});
const ocVersions = {
withExceptions: null,
single: null,
current: null,
};

let OC = Promise.reject("OpenCascade not initialized");

function enableExceptions() {
if (!ocVersions.withExceptions) {
ocVersions.withExceptions = initOpenCascadeWithExceptions();
}
ocVersions.current = "withExceptions";
OC = ocVersions.withExceptions;
}

function disableExceptions() {
if (!ocVersions.single) {
ocVersions.single = initOpenCascade();
}
ocVersions.current = "single";
OC = ocVersions.single;
}

async function toggleExceptions() {
if (ocVersions.current === "single") {
enableExceptions();
} else {
disableExceptions();
}

await OC;
return ocVersions.current;
}

disableExceptions();

const shapeOrSketch = (shape) => {
if (!(shape instanceof replicad.Sketch)) return shape;
Expand Down Expand Up @@ -137,9 +171,19 @@ const buildShapesFromCode = async (code, params) => {
try {
shapes = await runCode(code, params);
} catch (e) {
console.error(e);

const message = e.message || `Kernel error ${e.toString()}`;
let message = "error";

if (typeof e === "number") {
if (oc.OCJS) {
const error = oc.OCJS.getStandard_FailureData(e);
message = error.GetMessageString();
} else {
message = `Kernel error ${e}`;
}
} else {
message = e.message;
console.error(e);
}

return {
error: true,
Expand Down Expand Up @@ -273,6 +317,8 @@ const service = {
exportShape,
edgeInfo,
faceInfo,
toggleExceptions,
exceptionsEnabled: () => ocVersions.current === "withExceptions",
};

expose(service, self);
Expand Down
1 change: 1 addition & 0 deletions packages/studio/src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import App from "./App.jsx";
import GlobalStyle from "./GlobalStyles.jsx";

import "replicad-opencascadejs/src/replicad_single.wasm?url";
import "replicad-opencascadejs/src/replicad_with_exceptions.wasm?url";

import { BrowserRouter } from "react-router-dom";

Expand Down
10 changes: 10 additions & 0 deletions packages/studio/src/initOCWithExceptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import opencascade from "replicad-opencascadejs/src/replicad_with_exceptions.js";
import opencascadeWasm from "replicad-opencascadejs/src/replicad_with_exceptions.wasm?url";

export default async () => {
const OC = await opencascade({
locateFile: () => opencascadeWasm,
});

return OC;
};
6 changes: 6 additions & 0 deletions packages/studio/src/visualiser/editor/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const AppState = types
error: false,
faceInfo: null,
processingInfo: null,
exceptionMode: "single",
}))
.actions((self) => ({
updateCode(newCode) {
Expand All @@ -74,6 +75,10 @@ const AppState = types
self.updateCode(code);
}),

toggleExceptions: flow(function* toggleExceptions() {
self.exceptionMode = yield api.toggleExceptions();
}),

process: flow(function* process(params) {
self.ui.deHighlight();
self.processing = true;
Expand Down Expand Up @@ -114,6 +119,7 @@ const AppState = types

const run = async () => {
if (!self.currentValues.code) return;
self.exceptionMode;
await processor();
};

Expand Down
36 changes: 36 additions & 0 deletions packages/studio/src/workbench/Autoload.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ const ErrorOverlay = styled(InfoBottomLeft)`
}
`;

const InfoOverlay = styled(InfoBottomLeft)`
border-color: var(--color-primary-light);
background-color: white;
border-width: 2px;
max-height: initial;
max-width: 50vw;
max-height: 90vw;
z-index: 1000;
`;

const RightAligned = styled.div`
display: flex;
justify-content: flex-end;
`;

export default observer(function AutoloadButton() {
const store = useEditorStore();
const toggleAutoload = useAutoload();
Expand All @@ -80,8 +96,28 @@ export default observer(function AutoloadButton() {
<div>Error</div>
<div>{store.error?.message}</div>
{store.error.stack && <pre>{store.error.stack}</pre>}

<RightAligned>
<Button onClick={store.toggleExceptions}>
Toggle full exceptions
</Button>
</RightAligned>
</ErrorOverlay>
)}
{!store.error && store.exceptionMode == "withExceptions" && (
<InfoOverlay>
<div>
You are currently in full exception mode. This means that the
computations are slower but will give you better information about
kernel errors.
</div>
<RightAligned>
<Button onClick={store.toggleExceptions}>
Disable full exception mode
</Button>
</RightAligned>
</InfoOverlay>
)}
</>
);
});
97 changes: 70 additions & 27 deletions packages/studio/src/workbench/EditorPane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ import Download from "../icons/Download";
import Share from "../icons/Share";
import LoadingScreen from "../components/LoadingScreen";
import { LinkEditor } from "../components/LinkEditor";
import { Button } from "../components/Button";

import { Dialog, DialogTitle, DialogBody } from "../components/Dialog.jsx";
import { useAutoload } from "./Autoload";
import Reload from "../icons/Reload";

export const ErrorOverlay = styled.div`
display: flex;
flex-direction: column;
min-width: 100%;
gap: 0.4em;
padding: 2em;
border-color: red;
border-width: 2px;
Expand All @@ -43,6 +48,21 @@ export const ErrorOverlay = styled.div`
}
`;

export const InfoOverlay = styled.div`
padding: 2em;
font-size: 0.7em;
position: absolute;
height: 100px;
width: 100%;
bottom: 0;
background-color: #f2e0de;
`;

const RightAligned = styled.div`
display: flex;
justify-content: flex-end;
`;

export default observer(function EditorPane() {
const store = useEditorStore();

Expand All @@ -66,34 +86,57 @@ export default observer(function EditorPane() {
if (!store.code.initialized) return <LoadingScreen />;

return (
<Splitter
direction={SplitDirection.Vertical}
gutterTheme={GutterTheme.Dark}
gutterClassName="custom-gutter-theme"
initialSizes={store.error ? [75, 25] : [100]}
>
<Editor
defaultLanguage="javascript"
defaultValue={store.code.current}
theme="vs-dark"
height="100%"
onChange={(e) => {
store.code.update(e, true);
}}
onMount={handleEditorDidMount}
options={{
automaticLayout: true,
minimap: { enabled: false },
}}
/>
{store.error && (
<ErrorOverlay>
<div>Error</div>
<div>{store.error?.message}</div>
{store.error.stack && <pre>{store.error.stack}</pre>}
</ErrorOverlay>
<>
<Splitter
direction={SplitDirection.Vertical}
gutterTheme={GutterTheme.Dark}
gutterClassName="custom-gutter-theme"
initialSizes={store.error ? [75, 25] : [100]}
>
<Editor
defaultLanguage="javascript"
defaultValue={store.code.current}
theme="vs-dark"
height="100%"
onChange={(e) => {
store.code.update(e, true);
}}
onMount={handleEditorDidMount}
options={{
automaticLayout: true,
minimap: { enabled: false },
}}
/>
{store.error && (
<ErrorOverlay>
<div>Error</div>
<div>{store.error?.message}</div>
{store.error.stack && <pre>{store.error.stack}</pre>}
{store.exceptionMode == "single" && (
<RightAligned>
<Button onClick={store.toggleExceptions}>
Enable full exception mode
</Button>
</RightAligned>
)}
</ErrorOverlay>
)}
</Splitter>
{store.exceptionMode == "withExceptions" && (
<InfoOverlay>
<div>
You are currently in full exception mode. This means that the
computations are slower but will give you better information about
kernel errors.
</div>
<RightAligned>
<Button onClick={store.toggleExceptions}>
Disable full exception mode
</Button>
</RightAligned>
</InfoOverlay>
)}
</Splitter>
</>
);
});

Expand Down

0 comments on commit 2e89f98

Please sign in to comment.