rudimentary error reporting
This commit is contained in:
parent
6eab20bb25
commit
1c0fa7197c
|
@ -2,9 +2,9 @@ const defaultBrush = `
|
||||||
; This is your brush.
|
; This is your brush.
|
||||||
; Feel free to edit it to your liking!
|
; Feel free to edit it to your liking!
|
||||||
(stroke
|
(stroke
|
||||||
8 ; thickness
|
8 ; thickness
|
||||||
(rgba 0.0 0.0 0.0 1.0) ; color
|
(rgba 0.0 0.0 0.0 1.0) ; color
|
||||||
(vec)) ; position
|
(vec)) ; position
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
||||||
export class BrushEditor extends HTMLElement {
|
export class BrushEditor extends HTMLElement {
|
||||||
|
@ -28,11 +28,51 @@ export class BrushEditor extends HTMLElement {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.errorHeader = this.appendChild(document.createElement("h1"));
|
||||||
|
this.errorHeader.classList.add("error-header");
|
||||||
|
|
||||||
|
this.errorArea = this.appendChild(document.createElement("pre"));
|
||||||
|
this.errorArea.classList.add("errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
get code() {
|
get code() {
|
||||||
return this.textArea.textContent;
|
return this.textArea.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetErrors() {
|
||||||
|
this.errorHeader.textContent = "";
|
||||||
|
this.errorArea.textContent = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHakuResult(phase, result) {
|
||||||
|
this.resetErrors();
|
||||||
|
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
if (result.status != "error") return;
|
||||||
|
|
||||||
|
this.errorHeader.textContent = `${phase} failed`;
|
||||||
|
|
||||||
|
if (result.errorKind == "diagnostics") {
|
||||||
|
// This is kind of wooden; I'd prefer if the error spans were rendered inline in text,
|
||||||
|
// but I haven't integrated anything for syntax highlighting yet that would let me
|
||||||
|
// do that.
|
||||||
|
this.errorArea.textContent = result.diagnostics
|
||||||
|
.map(
|
||||||
|
(diagnostic) => `${diagnostic.start}..${diagnostic.end}: ${diagnostic.message}`,
|
||||||
|
)
|
||||||
|
.join("\n");
|
||||||
|
} else if (result.errorKind == "plain") {
|
||||||
|
this.errorHeader.textContent = result.message;
|
||||||
|
} else if (result.errorKind == "exception") {
|
||||||
|
// TODO: This should show a stack trace.
|
||||||
|
this.errorArea.textContent = `an exception occurred: ${result.message}`;
|
||||||
|
} else {
|
||||||
|
console.warn(`unknown error kind: ${result.errorKind}`);
|
||||||
|
this.errorHeader.textContent = "(unknown error kind)";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("rkgk-brush-editor", BrushEditor);
|
customElements.define("rkgk-brush-editor", BrushEditor);
|
||||||
|
|
|
@ -60,6 +60,10 @@ button, textarea, input {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
font-family: "Fira Code", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main container layout */
|
/* Main container layout */
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
@ -215,7 +219,24 @@ rkgk-brush-editor {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
resize: none;
|
resize: none;
|
||||||
font-family: "Fira Code", monospace;
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.errors:empty, &>.error-header:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.error-header {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.errors {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--color-error);
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,20 @@ function readUrl() {
|
||||||
|
|
||||||
canvasRenderer.addEventListener(".paint", async (event) => {
|
canvasRenderer.addEventListener(".paint", async (event) => {
|
||||||
plotQueue.push({ x: event.x, y: event.y });
|
plotQueue.push({ x: event.x, y: event.y });
|
||||||
currentUser.renderBrushToChunks(wall, event.x, event.y);
|
|
||||||
|
if (currentUser.isBrushOk) {
|
||||||
|
brushEditor.resetErrors();
|
||||||
|
|
||||||
|
let result = currentUser.renderBrushToChunks(wall, event.x, event.y);
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
if (result.status == "error") {
|
||||||
|
brushEditor.renderHakuResult(
|
||||||
|
result.phase == "eval" ? "Evaluation" : "Rendering",
|
||||||
|
result.result,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
canvasRenderer.addEventListener(".viewportUpdate", () => reticleRenderer.render());
|
canvasRenderer.addEventListener(".viewportUpdate", () => reticleRenderer.render());
|
||||||
|
@ -191,10 +204,10 @@ function readUrl() {
|
||||||
updateUrl(session, canvasRenderer.viewport),
|
updateUrl(session, canvasRenderer.viewport),
|
||||||
);
|
);
|
||||||
|
|
||||||
currentUser.setBrush(brushEditor.code);
|
brushEditor.renderHakuResult("Compilation", currentUser.setBrush(brushEditor.code));
|
||||||
brushEditor.addEventListener(".codeChanged", async () => {
|
brushEditor.addEventListener(".codeChanged", async () => {
|
||||||
flushPlotQueue();
|
flushPlotQueue();
|
||||||
currentUser.setBrush(brushEditor.code);
|
brushEditor.renderHakuResult("Compilation", currentUser.setBrush(brushEditor.code));
|
||||||
session.sendSetBrush(brushEditor.code);
|
session.sendSetBrush(brushEditor.code);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBrushToChunks(wall, x, y) {
|
renderBrushToChunks(wall, x, y) {
|
||||||
this.painter.renderBrushToWall(this.haku, x, y, wall);
|
return this.painter.renderBrushToWall(this.haku, x, y, wall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ export class Painter {
|
||||||
|
|
||||||
renderBrushToWall(haku, centerX, centerY, wall) {
|
renderBrushToWall(haku, centerX, centerY, wall) {
|
||||||
let evalResult = haku.evalBrush();
|
let evalResult = haku.evalBrush();
|
||||||
if (evalResult.status != "ok") return evalResult;
|
if (evalResult.status != "ok")
|
||||||
|
return { status: "error", phase: "eval", result: evalResult };
|
||||||
|
|
||||||
let left = centerX - this.paintArea / 2;
|
let left = centerX - this.paintArea / 2;
|
||||||
let top = centerY - this.paintArea / 2;
|
let top = centerY - this.paintArea / 2;
|
||||||
|
@ -21,7 +22,10 @@ export class Painter {
|
||||||
let chunk = wall.getOrCreateChunk(chunkX, chunkY);
|
let chunk = wall.getOrCreateChunk(chunkX, chunkY);
|
||||||
|
|
||||||
let renderResult = haku.renderValue(chunk.pixmap, x, y);
|
let renderResult = haku.renderValue(chunk.pixmap, x, y);
|
||||||
if (renderResult.status != "ok") return renderResult;
|
if (renderResult.status != "ok") {
|
||||||
|
haku.resetVm();
|
||||||
|
return { status: "error", phase: "render", result: renderResult };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
haku.resetVm();
|
haku.resetVm();
|
||||||
|
@ -32,5 +36,7 @@ export class Painter {
|
||||||
chunk.syncFromPixmap();
|
chunk.syncFromPixmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { status: "ok" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue