From 785ddff7067d4bf6590c9ad53716a46b1406e3df Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 19 Dec 2017 12:53:12 -0800 Subject: [PATCH 1/4] Reverting screen optimization to use SetInterval and didChange --- sim/state/screen.ts | 13 ++++++++++--- sim/visuals/board.ts | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sim/state/screen.ts b/sim/state/screen.ts index 342b0430..17810a6f 100644 --- a/sim/state/screen.ts +++ b/sim/state/screen.ts @@ -7,6 +7,7 @@ namespace pxsim { export class EV3ScreenState { + changed: boolean points: Uint8Array; constructor() { this.points = new Uint8Array(visuals.SCREEN_WIDTH * visuals.SCREEN_HEIGHT) @@ -23,13 +24,13 @@ namespace pxsim { setPixel(x: number, y: number, v: number) { this.applyMode(OFF(x, y), v) - runtime.queueDisplayUpdate(); + this.changed = true; } clear() { for (let i = 0; i < this.points.length; ++i) this.points[i] = 0; - runtime.queueDisplayUpdate(); + this.changed = true; } blitLineCore(x: number, y: number, w: number, buf: RefBuffer, mode: Draw, offset = 0) { @@ -58,7 +59,7 @@ namespace pxsim { } } - runtime.queueDisplayUpdate(); + this.changed = true; } clearLine(x: number, y: number, w: number) { @@ -72,6 +73,12 @@ namespace pxsim { off++ } } + + didChange() { + const res = this.changed; + this.changed = false; + return res; + } } } diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 79be7b10..49bf13c4 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -136,6 +136,10 @@ namespace pxsim.visuals { this.board.updateSubscribers.push(() => this.updateState()); this.updateState(); } + let that = this; + window.setInterval(function(){ + that.updateScreen(); + }, 30); } public getView(): SVGAndSize { @@ -169,7 +173,6 @@ namespace pxsim.visuals { public updateState() { this.updateVisibleNodes(); - this.updateScreen(); } private updateVisibleNodes() { @@ -396,6 +399,7 @@ namespace pxsim.visuals { private updateScreen() { let state = ev3board().screenState; + if (!state.didChange()) return; const bBox = this.layoutView.getBrick().getScreenBBox(); if (!bBox || bBox.width == 0) return; From 2157af3e63e4d3fd0870d0550039ba7e1d51a397 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 19 Dec 2017 14:20:35 -0800 Subject: [PATCH 2/4] Using game loop instead of queueAnimationUpdate --- libs/ev3/ns.ts | 2 +- pxtarget.json | 6 +- sim/state/color.ts | 3 - sim/state/gyro.ts | 10 +- sim/state/light.ts | 5 +- sim/state/motors.ts | 66 +++++++++++++- sim/state/nodeTypes.ts | 4 + sim/state/screen.ts | 2 +- sim/state/sensor.ts | 5 + sim/state/ultrasonic.ts | 5 +- sim/visuals/board.ts | 132 ++++++++++++++++----------- sim/visuals/nodes/largeMotorView.ts | 30 +----- sim/visuals/nodes/mediumMotorView.ts | 30 +----- theme/blockly.less | 10 +- theme/site/globals/site.variables | 4 +- 15 files changed, 175 insertions(+), 139 deletions(-) diff --git a/libs/ev3/ns.ts b/libs/ev3/ns.ts index 10eb2464..422cc6bd 100644 --- a/libs/ev3/ns.ts +++ b/libs/ev3/ns.ts @@ -24,7 +24,7 @@ namespace music { } -//% color="#48150C" +//% color="#5F3109" namespace control { } diff --git a/pxtarget.json b/pxtarget.json index dcadbd44..ac5ef3f1 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -132,10 +132,10 @@ "logic": "#1E5AA8", "math": "#9DC3F7", "variables": "#B40000", - "text": "#F0890A", + "text": "#FCAC00", "advanced": "#969696", - "functions": "#064597", - "arrays": "#890058" + "functions": "#19325A", + "arrays": "#901F76" }, "monacoColors": { "editor.background": "#ecf6ff" diff --git a/sim/state/color.ts b/sim/state/color.ts index ca5bab18..cb83bc04 100644 --- a/sim/state/color.ts +++ b/sim/state/color.ts @@ -34,9 +34,6 @@ namespace pxsim { this.color = color; this.changed = true; this.valueChanged = true; - - runtime.queueDisplayUpdate(); - } getValue() { diff --git a/sim/state/gyro.ts b/sim/state/gyro.ts index 91fab7fc..32d3750a 100644 --- a/sim/state/gyro.ts +++ b/sim/state/gyro.ts @@ -22,20 +22,14 @@ namespace pxsim { setAngle(angle: number) { if (this.angle != angle) { this.angle = angle; - this.changed = true; - this.valueChanged = true; - - runtime.queueDisplayUpdate(); + this.setChangedState(); } } setRate(rate: number) { if (this.rate != rate) { this.rate = rate; - this.changed = true; - this.valueChanged = true; - - runtime.queueDisplayUpdate(); + this.setChangedState(); } } diff --git a/sim/state/light.ts b/sim/state/light.ts index 8cab2a82..cbf98c2b 100644 --- a/sim/state/light.ts +++ b/sim/state/light.ts @@ -12,8 +12,9 @@ namespace pxsim { namespace pxsim.output { export function setLights(pattern: number) { - const lightState = ev3board().getBrickNode().lightState; + const brickState = ev3board().getBrickNode(); + const lightState = brickState.lightState; lightState.lightPattern = pattern; - runtime.queueDisplayUpdate(); + brickState.setChangedState(); } } \ No newline at end of file diff --git a/sim/state/motors.ts b/sim/state/motors.ts index 02a02e58..f5ebadf5 100644 --- a/sim/state/motors.ts +++ b/sim/state/motors.ts @@ -1,9 +1,9 @@ namespace pxsim { - export class MotorNode extends BaseNode { + export abstract class MotorNode extends BaseNode { isOutput = true; - public angle: number = 0; + protected angle: number = 0; private speed: number; private large: boolean; @@ -18,7 +18,8 @@ namespace pxsim { if (this.speed != speed) { this.speed = speed; this.changed = true; - runtime.queueDisplayUpdate(); + this.setChangedState(); + this.playMotorAnimation(); } } @@ -50,8 +51,14 @@ namespace pxsim { start() { // TODO: implement - runtime.queueDisplayUpdate(); + this.setChangedState(); } + + public getAngle() { + return this.angle; + } + + protected abstract playMotorAnimation(): void; } export class MediumMotorNode extends MotorNode { @@ -60,6 +67,32 @@ namespace pxsim { constructor(port: number) { super(port); } + + protected lastMotorAnimationId: number; + protected playMotorAnimation() { + // Max medium motor RPM is 250 according to http://www.cs.scranton.edu/~bi/2015s-html/cs358/EV3-Motor-Guide.docx + const rotationsPerMinute = 250; // 250 rpm at speed 100 + const rotationsPerSecond = rotationsPerMinute / 60; + const fps = GAME_LOOP_FPS; + const rotationsPerFrame = rotationsPerSecond / fps; + let now; + let then = Date.now(); + let interval = 1000 / fps; + let delta; + let that = this; + function draw() { + that.lastMotorAnimationId = requestAnimationFrame(draw); + now = Date.now(); + delta = now - then; + if (delta > interval) { + then = now - (delta % interval); + const rotations = that.getSpeed() / 100 * rotationsPerFrame; + const angle = rotations * 360; + that.angle += angle; + } + } + draw(); + } } export class LargeMotorNode extends MotorNode { @@ -69,5 +102,30 @@ namespace pxsim { super(port); } + protected lastMotorAnimationId: number; + protected playMotorAnimation() { + // Max medium motor RPM is 170 according to http://www.cs.scranton.edu/~bi/2015s-html/cs358/EV3-Motor-Guide.docx + const rotationsPerMinute = 170; // 170 rpm at speed 100 + const rotationsPerSecond = rotationsPerMinute / 60; + const fps = GAME_LOOP_FPS; + const rotationsPerFrame = rotationsPerSecond / fps; + let now; + let then = Date.now(); + let interval = 1000 / fps; + let delta; + let that = this; + function draw() { + that.lastMotorAnimationId = requestAnimationFrame(draw); + now = Date.now(); + delta = now - then; + if (delta > interval) { + then = now - (delta % interval); + const rotations = that.getSpeed() / 100 * rotationsPerFrame; + const angle = rotations * 360; + that.angle += angle; + } + } + draw(); + } } } \ No newline at end of file diff --git a/sim/state/nodeTypes.ts b/sim/state/nodeTypes.ts index 515818a6..9be45649 100644 --- a/sim/state/nodeTypes.ts +++ b/sim/state/nodeTypes.ts @@ -32,5 +32,9 @@ namespace pxsim { this.changed = false; return res; } + + setChangedState() { + this.changed = true; + } } } \ No newline at end of file diff --git a/sim/state/screen.ts b/sim/state/screen.ts index 17810a6f..d18f1a52 100644 --- a/sim/state/screen.ts +++ b/sim/state/screen.ts @@ -7,7 +7,7 @@ namespace pxsim { export class EV3ScreenState { - changed: boolean + changed: boolean = true; points: Uint8Array; constructor() { this.points = new Uint8Array(visuals.SCREEN_WIDTH * visuals.SCREEN_HEIGHT) diff --git a/sim/state/sensor.ts b/sim/state/sensor.ts index 2f79393d..ccef210b 100644 --- a/sim/state/sensor.ts +++ b/sim/state/sensor.ts @@ -43,6 +43,11 @@ namespace pxsim { this.valueChanged = false; return res; } + + setChangedState() { + this.changed = true; + this.valueChanged = false; + } } export class AnalogSensorNode extends SensorNode { diff --git a/sim/state/ultrasonic.ts b/sim/state/ultrasonic.ts index 714a1712..21103987 100644 --- a/sim/state/ultrasonic.ts +++ b/sim/state/ultrasonic.ts @@ -17,10 +17,7 @@ namespace pxsim { setDistance(distance: number) { if (this.distance != distance) { this.distance = distance; - this.changed = true; - this.valueChanged = true; - - runtime.queueDisplayUpdate(); + this.setChangedState(); } } diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 49bf13c4..a3de0361 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -1,5 +1,9 @@ /// +namespace pxsim { + export const GAME_LOOP_FPS = 32; +} + namespace pxsim.visuals { const EV3_STYLE = ` @@ -136,10 +140,6 @@ namespace pxsim.visuals { this.board.updateSubscribers.push(() => this.updateState()); this.updateState(); } - let that = this; - window.setInterval(function(){ - that.updateScreen(); - }, 30); } public getView(): SVGAndSize { @@ -171,53 +171,6 @@ namespace pxsim.visuals { this.layoutView.updateTheme(theme); } - public updateState() { - this.updateVisibleNodes(); - } - - private updateVisibleNodes() { - const inputNodes = ev3board().getInputNodes(); - inputNodes.forEach((node, index) => { - const view = this.getDisplayViewForNode(node.id, index); - if (view) { - this.layoutView.setInput(index, view); - view.updateState(); - } - }); - - this.getDisplayViewForNode(ev3board().getBrickNode().id, -1).updateState(); - - const outputNodes = ev3board().getMotors(); - outputNodes.forEach((node, index) => { - const view = this.getDisplayViewForNode(node.id, index); - if (view) { - this.layoutView.setOutput(index, view); - view.updateState(); - } - }); - - const selected = this.layoutView.getSelected(); - if (selected && (selected.getId() !== this.selectedNode || selected.getPort() !== this.selectedPort)) { - this.selectedNode = selected.getId(); - this.selectedPort = selected.getPort(); - this.controlGroup.clear(); - const control = this.getControlForNode(this.selectedNode, selected.getPort()); - if (control) { - this.controlView = control; - this.controlGroup.addView(control); - } - this.closeIconView.setVisible(true); - } else if (!selected) { - this.controlGroup.clear(); - this.controlView = undefined; - this.selectedNode = undefined; - this.selectedPort = undefined; - this.closeIconView.setVisible(false); - } - - this.resize(); - } - public resize() { const bounds = this.element.getBoundingClientRect(); this.width = bounds.width; @@ -245,7 +198,7 @@ namespace pxsim.visuals { this.controlView.translate(controlCoords.x, controlCoords.y); } - this.updateScreen(); + //this.updateScreen(); } private getControlForNode(id: NodeType, port: number) { @@ -358,7 +311,7 @@ namespace pxsim.visuals { this.closeIconView.setVisible(false); this.resize(); - this.updateState(); + //this.updateState(); // Add Screen canvas to board this.buildScreenCanvas(); @@ -397,7 +350,78 @@ namespace pxsim.visuals { this.screenCanvasTemp.style.display = 'none'; } - private updateScreen() { + private lastAnimationId: number; + public updateState() { + if (this.lastAnimationId) cancelAnimationFrame(this.lastAnimationId); + const fps = GAME_LOOP_FPS; + let now; + let then = Date.now(); + let interval = 1000 / fps; + let delta; + let that = this; + function loop() { + that.lastAnimationId = requestAnimationFrame(loop); + now = Date.now(); + delta = now - then; + if (delta > interval) { + then = now - (delta % interval); + that.updateStateStep(); + } + } + loop(); + } + + private updateStateStep() { + console.log("update state step"); + const inputNodes = ev3board().getInputNodes(); + inputNodes.forEach((node, index) => { + if (!node.didChange()) return; + const view = this.getDisplayViewForNode(node.id, index); + if (view) { + this.layoutView.setInput(index, view); + view.updateState(); + } + }); + + const brickNode = ev3board().getBrickNode(); + if (brickNode.didChange()) { + this.getDisplayViewForNode(ev3board().getBrickNode().id, -1).updateState(); + } + + const outputNodes = ev3board().getMotors(); + outputNodes.forEach((node, index) => { + if (!node.didChange()) return; + const view = this.getDisplayViewForNode(node.id, index); + if (view) { + this.layoutView.setOutput(index, view); + view.updateState(); + } + }); + + const selected = this.layoutView.getSelected(); + if (selected && (selected.getId() !== this.selectedNode || selected.getPort() !== this.selectedPort)) { + this.selectedNode = selected.getId(); + this.selectedPort = selected.getPort(); + this.controlGroup.clear(); + const control = this.getControlForNode(this.selectedNode, selected.getPort()); + if (control) { + this.controlView = control; + this.controlGroup.addView(control); + } + this.closeIconView.setVisible(true); + } else if (!selected) { + this.controlGroup.clear(); + this.controlView = undefined; + this.selectedNode = undefined; + this.selectedPort = undefined; + this.closeIconView.setVisible(false); + } + + this.updateScreenStep(); + //this.resize(); + } + + private updateScreenStep() { let state = ev3board().screenState; if (!state.didChange()) return; diff --git a/sim/visuals/nodes/largeMotorView.ts b/sim/visuals/nodes/largeMotorView.ts index 6dfdc850..a81886dc 100644 --- a/sim/visuals/nodes/largeMotorView.ts +++ b/sim/visuals/nodes/largeMotorView.ts @@ -18,36 +18,10 @@ namespace pxsim.visuals { if (this.lastMotorAnimationId) cancelAnimationFrame(this.lastMotorAnimationId); if (!speed) return; - this.playMotorAnimation(motorState); + this.setMotorAngle(motorState.getAngle()); } - private playMotorAnimation(state: MotorNode) { - // Max medium motor RPM is 170 according to http://www.cs.scranton.edu/~bi/2015s-html/cs358/EV3-Motor-Guide.docx - const rotationsPerMinute = 170; // 170 rpm at speed 100 - const rotationsPerSecond = rotationsPerMinute / 60; - const fps = MOTOR_ROTATION_FPS; - const rotationsPerFrame = rotationsPerSecond / fps; - let now; - let then = Date.now(); - let interval = 1000 / fps; - let delta; - let that = this; - function draw() { - that.lastMotorAnimationId = requestAnimationFrame(draw); - now = Date.now(); - delta = now - then; - if (delta > interval) { - then = now - (delta % interval); - that.playMotorAnimationStep(state.angle); - const rotations = state.getSpeed() / 100 * rotationsPerFrame; - const angle = rotations * 360; - state.angle += angle; - } - } - draw(); - } - - private playMotorAnimationStep(angle: number) { + private setMotorAngle(angle: number) { const holeEl = this.content.getElementById(this.normalizeId(LargeMotorView.ROTATING_ECLIPSE_ID)) const width = 34; const height = 34; diff --git a/sim/visuals/nodes/mediumMotorView.ts b/sim/visuals/nodes/mediumMotorView.ts index e53c8449..09d0e5a0 100644 --- a/sim/visuals/nodes/mediumMotorView.ts +++ b/sim/visuals/nodes/mediumMotorView.ts @@ -28,36 +28,10 @@ namespace pxsim.visuals { if (this.lastMotorAnimationId) cancelAnimationFrame(this.lastMotorAnimationId); if (!speed) return; - this.playMotorAnimation(motorState); + this.setMotorAngle(motorState.getAngle()); } - private playMotorAnimation(state: MotorNode) { - // Max medium motor RPM is 250 according to http://www.cs.scranton.edu/~bi/2015s-html/cs358/EV3-Motor-Guide.docx - const rotationsPerMinute = 250; // 250 rpm at speed 100 - const rotationsPerSecond = rotationsPerMinute / 60; - const fps = MOTOR_ROTATION_FPS; - const rotationsPerFrame = rotationsPerSecond / fps; - let now; - let then = Date.now(); - let interval = 1000 / fps; - let delta; - let that = this; - function draw() { - that.lastMotorAnimationId = requestAnimationFrame(draw); - now = Date.now(); - delta = now - then; - if (delta > interval) { - then = now - (delta % interval); - that.playMotorAnimationStep(state.angle); - const rotations = state.getSpeed() / 100 * rotationsPerFrame; - const angle = rotations * 360; - state.angle += angle; - } - } - draw(); - } - - private playMotorAnimationStep(angle: number) { + private setMotorAngle(angle: number) { const holeEl = this.content.getElementById(this.normalizeId(MediumMotorView.ROTATING_ECLIPSE_ID)) const width = 47.9; const height = 47.2; diff --git a/theme/blockly.less b/theme/blockly.less index a2571983..4d980269 100644 --- a/theme/blockly.less +++ b/theme/blockly.less @@ -28,9 +28,14 @@ div.blocklyTreeRow { border-radius: 0px; - -webkit-box-shadow: inset 0px 0px 0px 3px rgba(0,0,0,0.2); + margin-bottom: 7px; + /*-webkit-box-shadow: inset 0px 0px 0px 3px rgba(0,0,0,0.2); -moz-box-shadow: inset 0px 0px 0px 3px rgba(0,0,0,0.2); - box-shadow: inset 0px 0px 0px 3px rgba(0,0,0,0.2); + box-shadow: inset 0px 0px 0px 3px rgba(0,0,0,0.2);*/ +} + +div.blocklyTreeSeparator { + border-bottom: solid #CEA403 2px; } /* Remove shadow around blockly blocks */ @@ -51,6 +56,7 @@ span.blocklyTreeLabel { margin: 0.5rem; margin-left: 1rem; margin-right: 1rem; + margin-bottom: 0.8rem; } .blocklySearchInputField { border-radius: 1rem !important; diff --git a/theme/site/globals/site.variables b/theme/site/globals/site.variables index 9b19db37..7366f297 100644 --- a/theme/site/globals/site.variables +++ b/theme/site/globals/site.variables @@ -10,7 +10,7 @@ @emSize : 14px; @fontSize : 13px; -@primaryColor: @red; +@primaryColor: @blue; @secondaryColor: @yellow; @teal:#08415C; @@ -88,6 +88,8 @@ @pageBackground: #fff; +@positiveColor: @blue; +@defaultBorderRadius: 0px; @inputPlaceholderColor: lighten(@inputColor, 80); From ef5fa9ae827a324b4e4f2d3e86eb45737b4d551a Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 19 Dec 2017 14:55:43 -0800 Subject: [PATCH 3/4] Minor fix to killing the animation when the sim is killed --- sim/visuals/board.ts | 16 +++++++++++++--- sim/visuals/controls/distanceSlider.ts | 3 +-- sim/visuals/controls/rotationSlider.ts | 3 +-- sim/visuals/nodes/brickView.ts | 4 ---- sim/visuals/view.ts | 19 ------------------- 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index a3de0361..b3429ad7 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -140,6 +140,12 @@ namespace pxsim.visuals { this.board.updateSubscribers.push(() => this.updateState()); this.updateState(); } + + Runtime.messagePosted = (msg) => { + switch (msg.type || "") { + case "status": if ((msg as pxsim.SimulatorStateMessage).state == "killed") this.kill(); break; + } + } } public getView(): SVGAndSize { @@ -350,6 +356,10 @@ namespace pxsim.visuals { this.screenCanvasTemp.style.display = 'none'; } + private kill() { + if (this.lastAnimationId) cancelAnimationFrame(this.lastAnimationId); + } + private lastAnimationId: number; public updateState() { if (this.lastAnimationId) cancelAnimationFrame(this.lastAnimationId); @@ -372,7 +382,7 @@ namespace pxsim.visuals { } private updateStateStep() { - console.log("update state step"); + const selected = this.layoutView.getSelected(); const inputNodes = ev3board().getInputNodes(); inputNodes.forEach((node, index) => { if (!node.didChange()) return; @@ -398,7 +408,6 @@ namespace pxsim.visuals { } }); - const selected = this.layoutView.getSelected(); if (selected && (selected.getId() !== this.selectedNode || selected.getPort() !== this.selectedPort)) { this.selectedNode = selected.getId(); this.selectedPort = selected.getPort(); @@ -409,16 +418,17 @@ namespace pxsim.visuals { this.controlGroup.addView(control); } this.closeIconView.setVisible(true); + this.resize(); } else if (!selected) { this.controlGroup.clear(); this.controlView = undefined; this.selectedNode = undefined; this.selectedPort = undefined; this.closeIconView.setVisible(false); + this.resize(); } this.updateScreenStep(); - //this.resize(); } private updateScreenStep() { diff --git a/sim/visuals/controls/distanceSlider.ts b/sim/visuals/controls/distanceSlider.ts index 466cd24e..033b8b0d 100644 --- a/sim/visuals/controls/distanceSlider.ts +++ b/sim/visuals/controls/distanceSlider.ts @@ -78,7 +78,7 @@ namespace pxsim.visuals { return this.getInnerHeight() * 0.6; } - onBoardStateChanged() { + updateState() { if (!this.isVisible) { return; } @@ -91,7 +91,6 @@ namespace pxsim.visuals { onComponentVisible() { super.onComponentVisible(); this.isVisible = true; - this.onBoardStateChanged(); } onComponentHidden() { diff --git a/sim/visuals/controls/rotationSlider.ts b/sim/visuals/controls/rotationSlider.ts index c3539b4b..df5d8117 100644 --- a/sim/visuals/controls/rotationSlider.ts +++ b/sim/visuals/controls/rotationSlider.ts @@ -60,7 +60,7 @@ namespace pxsim.visuals { return this.getInnerHeight() / 4; } - onBoardStateChanged() { + updateState() { if (!this.isVisible) { return; } @@ -74,7 +74,6 @@ namespace pxsim.visuals { onComponentVisible() { super.onComponentVisible(); this.isVisible = true; - this.onBoardStateChanged(); } onComponentHidden() { diff --git a/sim/visuals/nodes/brickView.ts b/sim/visuals/nodes/brickView.ts index 9ff648d2..8619f053 100644 --- a/sim/visuals/nodes/brickView.ts +++ b/sim/visuals/nodes/brickView.ts @@ -35,10 +35,6 @@ namespace pxsim.visuals { return false; } - public shouldUpdateState() { - return true; - } - public updateState() { this.updateLight(); } diff --git a/sim/visuals/view.ts b/sim/visuals/view.ts index 9b5d27e6..029f139d 100644 --- a/sim/visuals/view.ts +++ b/sim/visuals/view.ts @@ -61,10 +61,6 @@ namespace pxsim.visuals { } } - public shouldUpdateState() { - return true; - } - public updateState() { } @@ -179,23 +175,8 @@ namespace pxsim.visuals { public setSelected(selected: boolean) { } protected getView() { - if (!this.rendered) { - this.subscribe(); - } return super.getView(); } - - protected onBoardStateChanged() { - // To be implemented by sub class - } - - protected subscribe() { - board().updateSubscribers.push(() => { - if (this.state.didChange()) { - this.onBoardStateChanged(); - } - }); - } } export class ViewContainer extends View { From 1ab7ae6cfac6f3b27fbd1867951b6ab0149f4865 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 19 Dec 2017 14:57:28 -0800 Subject: [PATCH 4/4] minor PR feedback --- sim/state/light.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sim/state/light.ts b/sim/state/light.ts index cbf98c2b..a2616fd3 100644 --- a/sim/state/light.ts +++ b/sim/state/light.ts @@ -14,7 +14,9 @@ namespace pxsim.output { export function setLights(pattern: number) { const brickState = ev3board().getBrickNode(); const lightState = brickState.lightState; - lightState.lightPattern = pattern; - brickState.setChangedState(); + if (lightState.lightPattern != pattern) { + lightState.lightPattern = pattern; + brickState.setChangedState(); + } } } \ No newline at end of file