diff --git a/src/engine/blocks.js b/src/engine/blocks.js index 92a2d58e7..7564d3ca9 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -226,7 +226,8 @@ class Blocks { id: e.blockId, element: e.element, name: e.name, - value: e.newValue + value: e.newValue, + isSpriteSpecific: e.isSpriteSpecific }, optRuntime); break; case 'move': @@ -326,12 +327,14 @@ class Blocks { break; case 'checkbox': block.isMonitored = args.value; + block.targetId = args.isSpriteSpecific ? this._getTargetIdFromBlockId(block.id) : null; if (optRuntime && wasMonitored && !block.isMonitored) { optRuntime.requestRemoveMonitor(block.id); } else if (optRuntime && !wasMonitored && block.isMonitored) { optRuntime.requestAddMonitor(MonitorRecord({ // @todo(vm#564) this will collide if multiple sprites use same block id: block.id, + spriteName: block.targetId ? optRuntime.getTargetById(block.targetId).getName() : null, opcode: block.opcode, params: this._getBlockParams(block), // @todo(vm#565) for numerical values with decimals, some countries use comma @@ -406,12 +409,17 @@ class Blocks { runAllMonitored (runtime) { Object.keys(this._blocks).forEach(blockId => { if (this.getBlock(blockId).isMonitored) { - // @todo handle specific targets (e.g. apple x position) - runtime.addMonitorScript(blockId); + const targetId = this.getBlock(blockId).targetId; + runtime.addMonitorScript(blockId, targetId ? runtime.getTargetById(targetId) : null); } }); } + _getTargetIdFromBlockId (blockId) { + // First word of block ID. See makeToolboxXML in scratch-gui + return blockId.split('_')[0]; + } + /** * Block management: delete blocks and their associated scripts. * @param {!object} e Blockly delete event to be processed. diff --git a/src/engine/execute.js b/src/engine/execute.js index df9b5964b..fe1688e6a 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -68,8 +68,10 @@ const handleReport = function ( sequencer.runtime.visualReport(currentBlockId, resolvedValue); } if (thread.updateMonitor) { + const targetId = sequencer.runtime.monitorBlocks.getBlock(currentBlockId).targetId; sequencer.runtime.requestUpdateMonitor(Map({ id: currentBlockId, + spriteName: targetId ? sequencer.runtime.getTargetById(targetId).getName() : null, value: String(resolvedValue) })); } diff --git a/src/engine/monitor-record.js b/src/engine/monitor-record.js index 76ed08489..40e67c5e7 100644 --- a/src/engine/monitor-record.js +++ b/src/engine/monitor-record.js @@ -2,6 +2,8 @@ const {Record} = require('immutable'); const MonitorRecord = Record({ id: null, + /** Present only if the monitor is sprite-specific, such as x position */ + spriteName: null, opcode: null, value: null, params: null diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 56fceadfc..06d068bcd 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -838,7 +838,7 @@ class Runtime extends EventEmitter { /** * Enqueue a script that when finished will update the monitor for the block. * @param {!string} topBlockId ID of block that starts the script. - * @param {?string} optTarget target ID for target to run script on. If not supplied, uses editing target. + * @param {?string} optTarget target Target to run script on. If not supplied, uses editing target. */ addMonitorScript (topBlockId, optTarget) { if (!optTarget) optTarget = this._editingTarget; @@ -1260,7 +1260,7 @@ class Runtime extends EventEmitter { * @param {!MonitorRecord} monitor Monitor to add. */ requestAddMonitor (monitor) { - this._monitorState = this._monitorState.set(monitor.id, monitor); + this._monitorState = this._monitorState.set(monitor.get('id'), monitor); } /** @@ -1271,9 +1271,10 @@ class Runtime extends EventEmitter { * the old monitor will keep its old value. */ requestUpdateMonitor (monitor) { - if (this._monitorState.has(monitor.get('id'))) { + const id = monitor.get('id'); + if (this._monitorState.has(id)) { this._monitorState = - this._monitorState.set(monitor.get('id'), this._monitorState.get(monitor.get('id')).merge(monitor)); + this._monitorState.set(id, this._monitorState.get(id).merge(monitor)); } } diff --git a/src/util/uid.js b/src/util/uid.js index fd4c41e87..34e8eaf58 100644 --- a/src/util/uid.js +++ b/src/util/uid.js @@ -6,9 +6,10 @@ * Legal characters for the unique ID. * Should be all on a US keyboard. No XML special characters or control codes. * Removed $ due to issue 251. + * Removed _ which denotes word separation in XML. * @private */ -const soup_ = '!#%()*+,-./:;=?@[]^_`{|}~' + +const soup_ = '!#%()*+,-./:;=?@[]^`{|}~' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; /**