diff --git a/src/blocks/scratch3_sensing.js b/src/blocks/scratch3_sensing.js index 6307b4c6a..ee4a009b4 100644 --- a/src/blocks/scratch3_sensing.js +++ b/src/blocks/scratch3_sensing.js @@ -313,12 +313,11 @@ class Scratch3SensingBlocks { } } - // Variables + // Target variables. const varName = args.PROPERTY; - for (const id in attrTarget.variables) { - if (attrTarget.variables[id].name === varName) { - return attrTarget.variables[id].value; - } + const variable = attrTarget.lookupVariableByNameAndType(varName, '', true); + if (variable) { + return variable.value; } // Otherwise, 0 diff --git a/src/engine/blocks.js b/src/engine/blocks.js index f2d792d6b..8b8575b94 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -567,6 +567,17 @@ class Blocks { if (!optRuntime){ break; } + // The selected item in the sensing of block menu needs to change based on the + // selected target. Set it to the first item in the menu list. + // TODO: (#1787) + if (block.opcode === 'sensing_of_object_menu') { + if (block.fields.OBJECT.value === '_stage_') { + this._blocks[block.parent].fields.PROPERTY.value = 'backdrop #'; + } else { + this._blocks[block.parent].fields.PROPERTY.value = 'x position'; + } + optRuntime.requestBlocksUpdate(); + } const flyoutBlock = block.shadow && block.parent ? this._blocks[block.parent] : block; if (flyoutBlock.isMonitored) { diff --git a/src/engine/runtime.js b/src/engine/runtime.js index c1f9c90fc..b53014c19 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -613,6 +613,14 @@ class Runtime extends EventEmitter { return 'RUNTIME_STARTED'; } + /** + * Event name for reporting that a block was updated and needs to be rerendered. + * @const {string} + */ + static get BLOCKS_NEED_UPDATE () { + return 'BLOCKS_NEED_UPDATE'; + } + /** * How rapidly we try to step threads by default, in ms. */ @@ -2169,6 +2177,13 @@ class Runtime extends EventEmitter { this._refreshTargets = true; } + /** + * Emit an event that indicate that the blocks on the workspace need updating. + */ + requestBlocksUpdate () { + this.emit(Runtime.BLOCKS_NEED_UPDATE); + } + /** * Set up timers to repeatedly step in a browser. */ diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 29b0be289..757e351c8 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -108,6 +108,9 @@ class VirtualMachine extends EventEmitter { this.runtime.on(Runtime.BLOCKSINFO_UPDATE, blocksInfo => { this.emit(Runtime.BLOCKSINFO_UPDATE, blocksInfo); }); + this.runtime.on(Runtime.BLOCKS_NEED_UPDATE, () => { + this.emitWorkspaceUpdate(); + }); this.runtime.on(Runtime.PERIPHERAL_LIST_UPDATE, info => { this.emit(Runtime.PERIPHERAL_LIST_UPDATE, info); }); diff --git a/test/unit/blocks_sensing.js b/test/unit/blocks_sensing.js index 58b9510c8..130b27d0b 100644 --- a/test/unit/blocks_sensing.js +++ b/test/unit/blocks_sensing.js @@ -229,6 +229,34 @@ test('loud? boolean', t => { t.end(); }); +test('get attribute of sprite variable', t => { + const rt = new Runtime(); + const sensing = new Sensing(rt); + const s = new Sprite(); + const target = new RenderedTarget(s, rt); + const variable = { + name: 'cars', + value: 'trucks', + type: '' + }; + // Add variable to set the map (it should be empty before this). + target.variables.anId = variable; + rt.getSpriteTargetByName = () => target; + t.equal(sensing.getAttributeOf({PROPERTY: 'cars'}), 'trucks'); + + t.end(); +}); +test('get attribute of variable that does not exist', t => { + const rt = new Runtime(); + const sensing = new Sensing(rt); + const s = new Sprite(); + const target = new RenderedTarget(s, rt); + rt.getTargetForStage = () => target; + t.equal(sensing.getAttributeOf({PROPERTY: 'variableThatDoesNotExist'}), 0); + + t.end(); +}); + test('username block', t => { const rt = new Runtime(); const sensing = new Sensing(rt);