Always diplay sad face on errors; use nullCheck() function; see https://github.com/Microsoft/pxt/issues/302

This commit is contained in:
Michal Moskal 2016-09-05 14:26:07 +01:00
parent 50293fc654
commit 61a29f7c67
4 changed files with 64 additions and 66 deletions

View File

@ -154,7 +154,7 @@ namespace pxsim.instructions {
//TODO: Refactor this function; it is too complicated. There is a lot of error-prone math being done
// to scale and place all elements which could be simplified with more forethought.
let svgEl = <SVGSVGElement>document.createElementNS("http://www.w3.org/2000/svg", "svg");
let dims = {l: 0, t: 0, w: 0, h: 0};
let dims = { l: 0, t: 0, w: 0, h: 0 };
let cmpSvgEl = <SVGSVGElement>document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgEl.appendChild(cmpSvgEl);
@ -181,7 +181,7 @@ namespace pxsim.instructions {
scale(opts.cmpHeight / dims.h)
}
svg.hydrate(cmpSvgEl, cmpSvgAtts);
let elDims = {l: dims.l, t: dims.t, w: dims.w, h: dims.h};
let elDims = { l: dims.l, t: dims.t, w: dims.w, h: dims.h };
let updateL = (newL: number) => {
if (newL < dims.l) {
@ -293,7 +293,7 @@ namespace pxsim.instructions {
let cnstr = builtinComponentPartVisual[builtinVis];
el = cnstr([0, 0]);
} else {
let partVis = <PartVisualDefinition> cmp;
let partVis = <PartVisualDefinition>cmp;
el = visuals.mkGenericPartSVG(partVis);
}
return wrapSvg(el, opts);
@ -320,7 +320,7 @@ namespace pxsim.instructions {
let step = w.assemblyStep + 1;
(stepToWires[step] || (stepToWires[step] = [])).push(w)
});
let getMaxStep = (ns: {assemblyStep: number}[]) => ns.reduce((m, n) => Math.max(m, n.assemblyStep), 0);
let getMaxStep = (ns: { assemblyStep: number }[]) => ns.reduce((m, n) => Math.max(m, n.assemblyStep), 0);
let stepOffset = powerWires.length > 0 ? getMaxStep(powerWires) + 2 : 1;
components.forEach(cAndWs => {
let {component, wires} = cAndWs;
@ -364,10 +364,10 @@ namespace pxsim.instructions {
function mkBlankBoardAndBreadboard(boardDef: BoardDefinition, cmpDefs: Map<PartDefinition>, fnArgs: any, width: number, buildMode: boolean = false): visuals.BoardHost {
let state = runtime.board as pxsim.DalBoard;
let boardHost = new visuals.BoardHost({
state: state,
boardDef: boardDef,
state: state,
boardDef: boardDef,
forceBreadboard: true,
cmpDefs: cmpDefs,
cmpDefs: cmpDefs,
maxWidth: `${width}px`,
fnArgs: fnArgs,
wireframe: buildMode,
@ -451,10 +451,10 @@ namespace pxsim.instructions {
// board and breadboard
let boardImg = mkBoardImgSvg(props.boardDef.visual);
let board = wrapSvg(boardImg, {left: QUANT_LBL(1), leftSize: QUANT_LBL_SIZE, cmpScale: PARTS_BOARD_SCALE});
let board = wrapSvg(boardImg, { left: QUANT_LBL(1), leftSize: QUANT_LBL_SIZE, cmpScale: PARTS_BOARD_SCALE });
panel.appendChild(board);
let bbRaw = mkBBSvg();
let bb = wrapSvg(bbRaw, {left: QUANT_LBL(1), leftSize: QUANT_LBL_SIZE, cmpScale: PARTS_BB_SCALE});
let bb = wrapSvg(bbRaw, { left: QUANT_LBL(1), leftSize: QUANT_LBL_SIZE, cmpScale: PARTS_BB_SCALE });
panel.appendChild(bb);
// components
@ -591,8 +591,8 @@ namespace pxsim.instructions {
if (tsCode) {
//we use the docs renderer to decompile the code to blocks and render it
//TODO: render the blocks code directly
let md =
`\`\`\`blocks
let md =
`\`\`\`blocks
${tsCode}
\`\`\`
\`\`\`package
@ -600,9 +600,9 @@ ${tsPackage}
\`\`\`
`
pxtdocs.requireMarked = function() { return (<any>window).marked; }
pxtdocs.requireMarked = function () { return (<any>window).marked; }
pxtrunner.renderMarkdownAsync(codeContainerDiv, md)
.done(function() {
.done(function () {
let codeSvg = $("#proj-code-container svg");
if (codeSvg.length > 0) {
//code rendered successfully as blocks

View File

@ -5,14 +5,33 @@
namespace pxsim {
export type BBRowCol = [/*row*/string, /*column*/string];
export type BoardPin = string;
export interface BBLoc {type: "breadboard", rowCol: BBRowCol};
export interface BoardLoc {type: "dalboard", pin: BoardPin};
export interface BBLoc { type: "breadboard", rowCol: BBRowCol };
export interface BoardLoc { type: "dalboard", pin: BoardPin };
export type Loc = BBLoc | BoardLoc;
export function initRuntimeWithDalBoard() {
U.assert(!runtime.board);
let b = new DalBoard();
runtime.board = b;
runtime.postError = (e) => {
led.setBrightness(255);
let img = board().ledMatrixState.image;
img.clear();
img.set(0, 4, 255);
img.set(1, 3, 255);
img.set(2, 3, 255);
img.set(3, 3, 255);
img.set(4, 4, 255);
img.set(0, 0, 255);
img.set(1, 0, 255);
img.set(0, 1, 255);
img.set(1, 1, 255);
img.set(3, 0, 255);
img.set(4, 0, 255);
img.set(3, 1, 255);
img.set(4, 1, 255);
runtime.updateDisplay();
}
}
if (!pxsim.initCurrentRuntime) {
pxsim.initCurrentRuntime = initRuntimeWithDalBoard;
@ -50,15 +69,15 @@ namespace pxsim.visuals {
move: "pointermove",
leave: "pointerleave"
} : {
up: "mouseup",
down: "mousedown",
move: "mousemove",
leave: "mouseleave"
};
up: "mouseup",
down: "mousedown",
move: "mousemove",
leave: "mouseleave"
};
export function translateEl(el: SVGElement, xy: [number, number]) {
//TODO append translation instead of replacing the full transform
svg.hydrate(el, {transform: `translate(${xy[0]} ${xy[1]})`});
svg.hydrate(el, { transform: `translate(${xy[0]} ${xy[1]})` });
}
export interface ComposeOpts {
@ -83,14 +102,14 @@ namespace pxsim.visuals {
export function composeSVG(opts: ComposeOpts): ComposeResult {
let [a, b] = [opts.el1, opts.el2];
U.assert(a.x == 0 && a.y == 0 && b.x == 0 && b.y == 0, "el1 and el2 x,y offsets not supported");
let setXY = (e: SVGSVGElement, x: number, y: number) => svg.hydrate(e, {x: x, y: y});
let setXY = (e: SVGSVGElement, x: number, y: number) => svg.hydrate(e, { x: x, y: y });
let setWH = (e: SVGSVGElement, w: string, h: string) => {
if (w)
svg.hydrate(e, {width: w});
svg.hydrate(e, { width: w });
if (h)
svg.hydrate(e, {height: h});
svg.hydrate(e, { height: h });
}
let setWHpx = (e: SVGSVGElement, w: number, h: number) => svg.hydrate(e, {width: `${w}px`, height: `${h}px`});
let setWHpx = (e: SVGSVGElement, w: number, h: number) => svg.hydrate(e, { width: `${w}px`, height: `${h}px` });
let scaleUnit = opts.scaleUnit2;
let aScalar = opts.scaleUnit2 / opts.scaleUnit1;
let bScalar = 1.0;
@ -157,11 +176,11 @@ namespace pxsim.visuals {
let w = scaleFn(opts.width);
let h = scaleFn(opts.height);
let img = <SVGImageElement>svg.elt("image", {
width: w,
height: h,
"href": `${opts.image}`
});
return {el: img, w: w, h: h, x: 0, y: 0};
width: w,
height: h,
"href": `${opts.image}`
});
return { el: img, w: w, h: h, x: 0, y: 0 };
}
export type Coord = [number, number];
@ -190,13 +209,15 @@ namespace pxsim.visuals {
export function mkTxt(cx: number, cy: number, size: number, rot: number, txt: string, txtXOffFactor?: number, txtYOffFactor?: number): SVGTextElement {
let el = <SVGTextElement>svg.elt("text")
//HACK: these constants (txtXOffFactor, txtYOffFactor) tweak the way this algorithm knows how to center the text
//HACK: these constants (txtXOffFactor, txtYOffFactor) tweak the way this algorithm knows how to center the text
txtXOffFactor = txtXOffFactor || -0.33333;
txtYOffFactor = txtYOffFactor || 0.3;
const xOff = txtXOffFactor * size * txt.length;
const yOff = txtYOffFactor * size;
svg.hydrate(el, {style: `font-size:${size}px;`,
transform: `translate(${cx} ${cy}) rotate(${rot}) translate(${xOff} ${yOff})` });
svg.hydrate(el, {
style: `font-size:${size}px;`,
transform: `translate(${cx} ${cy}) rotate(${rot}) translate(${xOff} ${yOff})`
});
svg.addClass(el, "noselect");
el.textContent = txt;
return el;

View File

@ -195,26 +195,24 @@ namespace pxsim.images {
namespace pxsim.ImageMethods {
export function showImage(leds: Image, offset: number) {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
runtime.queueDisplayUpdate()
}
export function plotImage(leds: Image, offset: number): void {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
runtime.queueDisplayUpdate()
}
export function height(leds: Image): number {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
return Image.height;
}
export function width(leds: Image): number {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
return leds.width;
}
@ -227,35 +225,32 @@ namespace pxsim.ImageMethods {
}
export function pixel(leds: Image, x: number, y: number): number {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
return leds.get(x, y);
}
export function setPixel(leds: Image, x: number, y: number, v: number) {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
leds.set(x, y, v);
}
export function clear(leds: Image) {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
leds.clear();
}
export function setPixelBrightness(i: Image, x: number, y: number, b: number) {
if (!i) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(i)
i.set(x, y, b);
}
export function pixelBrightness(i: Image, x: number, y: number): number {
if (!i) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(i)
return i.get(x, y);
}
export function scrollImage(leds: Image, stride: number, interval: number): void {
if (!leds) panic(PanicCode.MICROBIT_NULL_DEREFERENCE);
pxtrt.nullCheck(leds)
if (stride == 0) stride = 1;
let cb = getResume();

View File

@ -19,24 +19,6 @@ namespace pxsim {
export function panic(code: number) {
console.log("PANIC:", code)
led.setBrightness(255);
let img = board().ledMatrixState.image;
img.clear();
img.set(0, 4, 255);
img.set(1, 3, 255);
img.set(2, 3, 255);
img.set(3, 3, 255);
img.set(4, 4, 255);
img.set(0, 0, 255);
img.set(1, 0, 255);
img.set(0, 1, 255);
img.set(1, 1, 255);
img.set(3, 0, 255);
img.set(4, 0, 255);
img.set(3, 1, 255);
img.set(4, 1, 255);
runtime.updateDisplay();
throw new Error("PANIC " + code)
}