From 757dccd565ecc3367e5f637910b4e48e91aae24b Mon Sep 17 00:00:00 2001 From: DD Date: Tue, 14 Nov 2017 18:25:54 -0500 Subject: [PATCH] Move is sprite specific verification into VM in a temporary way. Remove monitors when their sprites are deleted. --- src/engine/blocks.js | 1 + src/engine/execute.js | 4 ++++ src/engine/monitor-record.js | 2 ++ src/engine/runtime.js | 9 +++++++++ src/virtual-machine.js | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/src/engine/blocks.js b/src/engine/blocks.js index 7564d3ca9..155a2e5e8 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -334,6 +334,7 @@ class Blocks { optRuntime.requestAddMonitor(MonitorRecord({ // @todo(vm#564) this will collide if multiple sprites use same block id: block.id, + targetId: block.targetId, spriteName: block.targetId ? optRuntime.getTargetById(block.targetId).getName() : null, opcode: block.opcode, params: this._getBlockParams(block), diff --git a/src/engine/execute.js b/src/engine/execute.js index fe1688e6a..bbacca951 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -69,6 +69,10 @@ const handleReport = function ( } if (thread.updateMonitor) { const targetId = sequencer.runtime.monitorBlocks.getBlock(currentBlockId).targetId; + if (targetId && !sequencer.runtime.getTargetById(targetId)) { + // Target no longer exists + return; + } sequencer.runtime.requestUpdateMonitor(Map({ id: currentBlockId, spriteName: targetId ? sequencer.runtime.getTargetById(targetId).getName() : null, diff --git a/src/engine/monitor-record.js b/src/engine/monitor-record.js index 40e67c5e7..d42b878f5 100644 --- a/src/engine/monitor-record.js +++ b/src/engine/monitor-record.js @@ -4,6 +4,8 @@ const MonitorRecord = Record({ id: null, /** Present only if the monitor is sprite-specific, such as x position */ spriteName: null, + /** Present only if the monitor is sprite-specific, such as x position */ + targetId: null, opcode: null, value: null, params: null diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 06d068bcd..6d650668e 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -1287,6 +1287,15 @@ class Runtime extends EventEmitter { this._monitorState = this._monitorState.delete(monitorId); } + /** + * Removes all monitors with the given target ID from the state. Does nothing if + * the monitor already does not exist in the state. + * @param {!string} targetId Remove all monitors with given target ID. + */ + requestRemoveMonitorByTargetId (targetId) { + this._monitorState = this._monitorState.filterNot(value => value.targetId === targetId); + } + /** * Get a target by its id. * @param {string} targetId Id of target to find. diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 6dfc7acad..175b5fd20 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -484,6 +484,7 @@ class VirtualMachine extends EventEmitter { if (!sprite) { throw new Error('No sprite associated with this target.'); } + this.runtime.requestRemoveMonitorByTargetId(targetId); const currentEditingTarget = this.editingTarget; for (let i = 0; i < sprite.clones.length; i++) { const clone = sprite.clones[i]; @@ -574,9 +575,44 @@ class VirtualMachine extends EventEmitter { * @param {!Blockly.Event} e Any Blockly event. */ monitorBlockListener (e) { + const tempMonitoredBlocks = [ + 'volume', + 'tempo', + 'answer', + 'loudness', + 'videoon', + 'timer', + 'of', + 'current', + 'username', + 'xposition', + 'yposition', + 'direction', + 'size', + 'backdropname', + 'costumeorder', + 'backdroporder' + ]; + const tempMonitoredPerSpriteBlocks = [ + 'xposition', + 'yposition', + 'direction', + 'size', + 'costumeorder' + ]; // Filter events by type, since monitor blocks only need to listen to these events. // Monitor blocks shouldn't be destroyed when flyout blocks are deleted. if (['create', 'change'].indexOf(e.type) !== -1) { + // TEMPORARY ---- + let blockType = e.blockId.split('_'); + blockType = blockType[blockType.length - 1]; + if (tempMonitoredBlocks.indexOf(blockType) === -1) { + return; + } + if (tempMonitoredPerSpriteBlocks.indexOf(blockType) !== -1) { + e.isSpriteSpecific = true; + } + // ----- this.runtime.monitorBlocks.blocklyListen(e, this.runtime); } }