diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js index 70238a786..a64f095b0 100644 --- a/src/blocks/scratch3_looks.js +++ b/src/blocks/scratch3_looks.js @@ -242,6 +242,15 @@ class Scratch3LooksBlocks { }; } + getMonitored () { + return { + size: {isSpriteSpecific: true}, + costumeorder: {isSpriteSpecific: true}, + backdroporder: {}, + backdropname: {} + }; + } + say (args, util) { // @TODO in 2.0 calling say/think resets the right/left bias of the bubble this._updateBubble(util.target, 'say', String(args.MESSAGE)); diff --git a/src/blocks/scratch3_motion.js b/src/blocks/scratch3_motion.js index d040337c8..b30138d3e 100644 --- a/src/blocks/scratch3_motion.js +++ b/src/blocks/scratch3_motion.js @@ -38,6 +38,14 @@ class Scratch3MotionBlocks { }; } + getMonitored () { + return { + xposition: {isSpriteSpecific: true}, + yposition: {isSpriteSpecific: true}, + direction: {isSpriteSpecific: true} + }; + } + moveSteps (args, util) { const steps = Cast.toNumber(args.STEPS); const radians = MathUtil.degToRad(90 - util.target.direction); diff --git a/src/blocks/scratch3_sensing.js b/src/blocks/scratch3_sensing.js index 17dc87e9d..d51dd5d3b 100644 --- a/src/blocks/scratch3_sensing.js +++ b/src/blocks/scratch3_sensing.js @@ -49,6 +49,16 @@ class Scratch3SensingBlocks { }; } + getMonitored () { + return { + answer: {}, + loudness: {}, + timer: {}, + of: {}, + current: {} + }; + } + _onAnswer (answer) { this._answer = answer; const questionObj = this._questionList.shift(); diff --git a/src/blocks/scratch3_sound.js b/src/blocks/scratch3_sound.js index 6f5fed972..d3f3f92ac 100644 --- a/src/blocks/scratch3_sound.js +++ b/src/blocks/scratch3_sound.js @@ -103,6 +103,12 @@ class Scratch3SoundBlocks { }; } + getMonitored () { + return { + volume: {} + }; + } + playSound (args, util) { const index = this._getSoundIndex(args.SOUND_MENU, util); if (index >= 0) { diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 6d650668e..d8fa88358 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -176,6 +176,13 @@ class Runtime extends EventEmitter { */ this._refreshTargets = false; + /** + * Map to look up all monitor block information by opcode. + * @type {object} + * @private + */ + this.monitorBlockInfo = {}; + /** * Ordered map of all monitors, which are MonitorReporter objects. */ @@ -225,6 +232,9 @@ class Runtime extends EventEmitter { // Register all given block packages. this._registerBlockPackages(); + // Populate monitorBlockInfo + this._registerMonitorInfo(); + // Register and initialize "IO devices", containers for processing // I/O related data. /** @type {Object.} */ @@ -451,6 +461,22 @@ class Runtime extends EventEmitter { this.emit(Runtime.EXTENSION_ADDED, categoryInfo.blocks.concat(categoryInfo.menus)); } + /** + * Populate this.monitorBlockInfo + */ + _registerMonitorInfo () { + for (const packageName in defaultBlockPackages) { + if (defaultBlockPackages.hasOwnProperty(packageName)) { + // @todo pass a different runtime depending on package privilege? + const packageObject = new (defaultBlockPackages[packageName])(this); + // Collect monitored from package. + if (packageObject.getMonitored) { + this.monitorBlockInfo = Object.assign({}, this.monitorBlockInfo, packageObject.getMonitored()); + } + } + } + } + /** * Build the scratch-blocks JSON for a menu. Note that scratch-blocks treats menus as a special kind of block. * @param {string} menuName - the name of the menu diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 175b5fd20..5c5361bae 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -575,44 +575,18 @@ 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) { + if (!this.runtime.monitorBlockInfo.hasOwnProperty(blockType)) { return; } - if (tempMonitoredPerSpriteBlocks.indexOf(blockType) !== -1) { + if (!this.runtime.monitorBlockInfo.hasOwnProperty(blockType) || + this.runtime.monitorBlockInfo[blockType].isSpriteSpecific) { e.isSpriteSpecific = true; } - // ----- this.runtime.monitorBlocks.blocklyListen(e, this.runtime); } }