From 0e7eae98d51752bc8f3b2244c73e9c4d2472972e Mon Sep 17 00:00:00 2001 From: Karishma Chadha Date: Thu, 8 Nov 2018 00:37:28 -0500 Subject: [PATCH 1/5] Separate out monitors for blocks reporter blocks that have parameters. --- src/blocks/scratch3_looks.js | 5 +++-- src/blocks/scratch3_sensing.js | 3 ++- src/engine/blocks.js | 41 +++++++++++++++++++++++++++++++--- src/serialization/sb2.js | 25 ++++++++++++++++----- src/util/get-monitor-id.js | 21 +++++++++++++++++ 5 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 src/util/get-monitor-id.js diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js index 21e56b376d4..e3ab68889a4 100644 --- a/src/blocks/scratch3_looks.js +++ b/src/blocks/scratch3_looks.js @@ -3,6 +3,7 @@ const Clone = require('../util/clone'); const RenderedTarget = require('../sprites/rendered-target'); const uid = require('../util/uid'); const StageLayering = require('../engine/stage-layering'); +const getMonitorIdForBlockWithArgs = require('../util/get-monitor-id'); /** * @typedef {object} BubbleState - the bubble state associated with a particular target. @@ -272,10 +273,10 @@ class Scratch3LooksBlocks { }, looks_costumenumbername: { isSpriteSpecific: true, - getId: targetId => `${targetId}_costumenumbername` + getId: (targetId, params) => getMonitorIdForBlockWithArgs(`${targetId}_costumenumbername`, params) }, looks_backdropnumbername: { - getId: () => 'backdropnumbername' + getId: (_, params) => getMonitorIdForBlockWithArgs('backdropnumbername', params) } }; } diff --git a/src/blocks/scratch3_sensing.js b/src/blocks/scratch3_sensing.js index 2dcb23ed650..b9dfb9d299d 100644 --- a/src/blocks/scratch3_sensing.js +++ b/src/blocks/scratch3_sensing.js @@ -1,5 +1,6 @@ const Cast = require('../util/cast'); const Timer = require('../util/timer'); +const getMonitorIdForBlockWithArgs = require('../util/get-monitor-id'); class Scratch3SensingBlocks { constructor (runtime) { @@ -89,7 +90,7 @@ class Scratch3SensingBlocks { // This is different from the default toolbox xml id in order to support // importing multiple monitors from the same opcode from sb2 files, // something that is not currently supported in scratch 3. - getId: (_, param) => `current_${param}` + getId: (_, params) => getMonitorIdForBlockWithArgs('current', params) // _${param}` } }; } diff --git a/src/engine/blocks.js b/src/engine/blocks.js index 858871f699c..acb6ecb8f3d 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -7,6 +7,7 @@ const {Map} = require('immutable'); const BlocksExecuteCache = require('./blocks-execute-cache'); const log = require('../util/log'); const Variable = require('./variable'); +const getMonitorIdForBlockWithArgs = require('../util/get-monitor-id'); /** * @fileoverview @@ -523,11 +524,20 @@ class Blocks { changeBlock (args, optRuntime) { // Validate if (['field', 'mutation', 'checkbox'].indexOf(args.element) === -1) return; - const block = this._blocks[args.id]; + let block = this._blocks[args.id]; if (typeof block === 'undefined') return; - const wasMonitored = block.isMonitored; switch (args.element) { case 'field': + // TODO when the field of a monitored block changes, + // update the checkbox in the flyout based on whether + // a monitor for that current combination of selected parameters exists + // e.g. + // 1. check (current [v year]) + // 2. switch dropdown in flyout block to (current [v minute]) + // 3. the checkbox should become unchecked if we're not already + // monitoring current minute + + // Update block value if (!block.fields[args.name]) return; if (args.name === 'VARIABLE' || args.name === 'LIST' || @@ -559,11 +569,36 @@ class Blocks { block.mutation = mutationAdapter(args.value); break; case 'checkbox': { - block.isMonitored = args.value; if (!optRuntime) { break; } + // A checkbox usually has a one to one correspondence with the monitor + // block but in the case of monitored reporters that have arguments, + // map the old id to a new id, creating a new monitor block if necessary + if (block.fields && Object.keys(block.fields).length > 0 && + block.opcode !== 'data_variable' && block.opcode !== 'data_listcontents') { + + // This block has an argument which needs to get separated out into multiple monitor blocks + const params = Object.keys(block.fields).map(k => block.fields[k].value); + const newId = getMonitorIdForBlockWithArgs(block.id, params); + // Note: we're not just constantly creating a longer and longer id everytime we check + // the checkbox because we're using the id of the block in the flyout as the base + + // check if a block withl the new id already exists, otherwise create + let newBlock = optRuntime.monitorBlocks.getBlock(newId); + if (!newBlock) { + newBlock = JSON.parse(JSON.stringify(block)); + newBlock.id = newId; + optRuntime.monitorBlocks.createBlock(newBlock); + } + + block = newBlock; // Carry on through the rest of this code with newBlock + } + + const wasMonitored = block.isMonitored; + block.isMonitored = args.value; + // Variable blocks may be sprite specific depending on the owner of the variable let isSpriteLocalVariable = false; if (block.opcode === 'data_variable') { diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index ac8eda01995..4fa8bba53fb 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -297,7 +297,13 @@ const parseMonitorObject = (object, runtime, targets, extensions) => { } else if (object.cmd === 'contentsOfList:') { block.id = getVariableId(object.param, Variable.LIST_TYPE); } else if (runtime.monitorBlockInfo.hasOwnProperty(block.opcode)) { - block.id = runtime.monitorBlockInfo[block.opcode].getId(target.id, object.param); + block.id = runtime.monitorBlockInfo[block.opcode].getId(target.id, [object.param]); + } else { + // If the opcode can't be found in the runtime monitorBlockInfo, + // then default to using the block opcode as the id instead. + // This is for extension monitors, and assumes that extension monitors + // cannot be sprite specific. + block.id = block.opcode; } // Block needs a targetId if it is targetting something other than the stage @@ -306,10 +312,19 @@ const parseMonitorObject = (object, runtime, targets, extensions) => { // Property required for running monitored blocks. block.isMonitored = object.visible; - // Blocks can be created with children, flatten and add to monitorBlocks. - const newBlocks = flatten([block]); - for (let i = 0; i < newBlocks.length; i++) { - runtime.monitorBlocks.createBlock(newBlocks[i]); + const existingMonitorBlock = runtime.monitorBlocks._blocks[block.id]; + if (existingMonitorBlock) { + // A monitor block already exists if the toolbox has been loaded and + // the monitor block is not target specific (because the block gets recycled). + // Update the existing block with the relevant monitor information. + existingMonitorBlock.isMonitored = object.visible; + existingMonitorBlock.targetId = block.targetId; + } else { + // Blocks can be created with children, flatten and add to monitorBlocks. + const newBlocks = flatten([block]); + for (let i = 0; i < newBlocks.length; i++) { + runtime.monitorBlocks.createBlock(newBlocks[i]); + } } // Convert numbered mode into strings for better understandability. diff --git a/src/util/get-monitor-id.js b/src/util/get-monitor-id.js new file mode 100644 index 00000000000..0f331b1ae48 --- /dev/null +++ b/src/util/get-monitor-id.js @@ -0,0 +1,21 @@ +/** + * Returns a string representing a unique id for a monitored block + * where a single reporter block can have more than one monitor + * (and therefore more than one monitor block) associated + * with it (e.g. when reporter blocks have inputs). + * @param {string} baseId The base id to use for the different monitor blocks + * @param {string[]} params A list of strings representing selected + * parameters on the block. + */ +// TODO this function should eventually be the single place where all monitor +// IDs are obtained given an opcode for the reporter block and the list of +// selected parameters. +const getMonitorIdForBlockWithArgs = function (id, params) { + let fieldString = ''; + for (const param of params) { + fieldString += `_${param}`; + } + return `${id}${fieldString}`; +}; + +module.exports = getMonitorIdForBlockWithArgs; From 7d1226458f17dfc56c285c668bf78f41d8c1ce2e Mon Sep 17 00:00:00 2001 From: Karishma Chadha Date: Thu, 8 Nov 2018 00:37:49 -0500 Subject: [PATCH 2/5] Fix import of current day of week block from sb2. --- src/serialization/sb2.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index 4fa8bba53fb..363a70523d6 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -297,6 +297,7 @@ const parseMonitorObject = (object, runtime, targets, extensions) => { } else if (object.cmd === 'contentsOfList:') { block.id = getVariableId(object.param, Variable.LIST_TYPE); } else if (runtime.monitorBlockInfo.hasOwnProperty(block.opcode)) { + if (object.param === 'day of week') object.param = 'DAYOFWEEK'; block.id = runtime.monitorBlockInfo[block.opcode].getId(target.id, [object.param]); } else { // If the opcode can't be found in the runtime monitorBlockInfo, @@ -1028,6 +1029,10 @@ const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extension value: providedArg }; + if (expectedArg.fieldName === 'CURRENTMENU' && providedArg === 'day of week') { + activeBlock.fields[expectedArg.fieldName].value = 'DAYOFWEEK'; + } + if (expectedArg.fieldName === 'VARIABLE') { // Add `id` property to variable fields activeBlock.fields[expectedArg.fieldName].id = getVariableId(providedArg, Variable.SCALAR_TYPE); From 5db3db3a927633d2f89a7833f833ee62d2da5c87 Mon Sep 17 00:00:00 2001 From: Karishma Chadha Date: Thu, 8 Nov 2018 01:33:26 -0500 Subject: [PATCH 3/5] monitor id getter should use block fields instead of a list of strings --- package-lock.json | 6 +++--- src/blocks/scratch3_looks.js | 4 ++-- src/blocks/scratch3_sensing.js | 2 +- src/engine/blocks.js | 6 +++--- src/serialization/sb2.js | 3 +-- src/util/get-monitor-id.js | 9 ++++----- test/integration/monitors.js | 4 +++- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0791258428a..2cfc11a5829 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11899,9 +11899,9 @@ } }, "scratch-render": { - "version": "0.1.0-prerelease.20181024220305", - "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20181024220305.tgz", - "integrity": "sha512-wbCVQW6qNJUsuUv6YDTfsKfmXCwI2r0W6wWqstNS2HojNigpYeBVG2SHFPQp/zDOzp/6q/uQkTN/pBOuDoEJpw==", + "version": "0.1.0-prerelease.20181102130522", + "resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20181102130522.tgz", + "integrity": "sha512-r6V3zzwXalhWR5xWN4miNht7FbYqF6On+p3n2USK4r2D6oaE5vh2aMwKSjt9OfEf/hfFJK63mJd+qeuJ1slKVQ==", "dev": true, "requires": { "grapheme-breaker": "0.3.2", diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js index e3ab68889a4..ebf40e5552c 100644 --- a/src/blocks/scratch3_looks.js +++ b/src/blocks/scratch3_looks.js @@ -273,10 +273,10 @@ class Scratch3LooksBlocks { }, looks_costumenumbername: { isSpriteSpecific: true, - getId: (targetId, params) => getMonitorIdForBlockWithArgs(`${targetId}_costumenumbername`, params) + getId: (targetId, fields) => getMonitorIdForBlockWithArgs(`${targetId}_costumenumbername`, fields) }, looks_backdropnumbername: { - getId: (_, params) => getMonitorIdForBlockWithArgs('backdropnumbername', params) + getId: (_, fields) => getMonitorIdForBlockWithArgs('backdropnumbername', fields) } }; } diff --git a/src/blocks/scratch3_sensing.js b/src/blocks/scratch3_sensing.js index b9dfb9d299d..6307b4c6a2c 100644 --- a/src/blocks/scratch3_sensing.js +++ b/src/blocks/scratch3_sensing.js @@ -90,7 +90,7 @@ class Scratch3SensingBlocks { // This is different from the default toolbox xml id in order to support // importing multiple monitors from the same opcode from sb2 files, // something that is not currently supported in scratch 3. - getId: (_, params) => getMonitorIdForBlockWithArgs('current', params) // _${param}` + getId: (_, fields) => getMonitorIdForBlockWithArgs('current', fields) // _${param}` } }; } diff --git a/src/engine/blocks.js b/src/engine/blocks.js index acb6ecb8f3d..4267c76e338 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -579,9 +579,9 @@ class Blocks { if (block.fields && Object.keys(block.fields).length > 0 && block.opcode !== 'data_variable' && block.opcode !== 'data_listcontents') { - // This block has an argument which needs to get separated out into multiple monitor blocks - const params = Object.keys(block.fields).map(k => block.fields[k].value); - const newId = getMonitorIdForBlockWithArgs(block.id, params); + // This block has an argument which needs to get separated out into + // multiple monitor blocks with ids based on the selected argument + const newId = getMonitorIdForBlockWithArgs(block.id, block.fields); // Note: we're not just constantly creating a longer and longer id everytime we check // the checkbox because we're using the id of the block in the flyout as the base diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index 363a70523d6..04df0093924 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -297,8 +297,7 @@ const parseMonitorObject = (object, runtime, targets, extensions) => { } else if (object.cmd === 'contentsOfList:') { block.id = getVariableId(object.param, Variable.LIST_TYPE); } else if (runtime.monitorBlockInfo.hasOwnProperty(block.opcode)) { - if (object.param === 'day of week') object.param = 'DAYOFWEEK'; - block.id = runtime.monitorBlockInfo[block.opcode].getId(target.id, [object.param]); + block.id = runtime.monitorBlockInfo[block.opcode].getId(target.id, block.fields); } else { // If the opcode can't be found in the runtime monitorBlockInfo, // then default to using the block opcode as the id instead. diff --git a/src/util/get-monitor-id.js b/src/util/get-monitor-id.js index 0f331b1ae48..ada1e7c7090 100644 --- a/src/util/get-monitor-id.js +++ b/src/util/get-monitor-id.js @@ -4,16 +4,15 @@ * (and therefore more than one monitor block) associated * with it (e.g. when reporter blocks have inputs). * @param {string} baseId The base id to use for the different monitor blocks - * @param {string[]} params A list of strings representing selected - * parameters on the block. + * @param {object} fields The monitor block's fields object. */ // TODO this function should eventually be the single place where all monitor // IDs are obtained given an opcode for the reporter block and the list of // selected parameters. -const getMonitorIdForBlockWithArgs = function (id, params) { +const getMonitorIdForBlockWithArgs = function (id, fields) { let fieldString = ''; - for (const param of params) { - fieldString += `_${param}`; + for (const fieldKey in fields) { + fieldString += `_${fields[fieldKey].value}`; } return `${id}${fieldString}`; }; diff --git a/test/integration/monitors.js b/test/integration/monitors.js index 38e89b43e36..bf273a4892c 100644 --- a/test/integration/monitors.js +++ b/test/integration/monitors.js @@ -60,7 +60,9 @@ test('importing sb2 project with monitors', t => { t.equal(monitorRecord.height, 202); // Backdrop name monitor is visible, not sprite specific - monitorRecord = vm.runtime._monitorState.get('backdropnumbername'); + // should get imported with id that references the name parameter + // via '_name' at the end since the 3.0 block has a dropdown. + monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name'); t.equal(monitorRecord.opcode, 'looks_backdropnumbername'); t.equal(monitorRecord.mode, 'default'); t.equal(monitorRecord.visible, true); From 87244b4110cc57bef0b3bddc9ea5608fd6d05395 Mon Sep 17 00:00:00 2001 From: Karishma Chadha Date: Thu, 8 Nov 2018 14:11:30 -0500 Subject: [PATCH 4/5] Normalize capitalization of sensing_current block fields during sb2 import and during monitor id generation. Update monitors integration test to include sensing_current block monitors. --- src/serialization/sb2.js | 9 +++++-- src/util/get-monitor-id.js | 15 ++++++++++- test/fixtures/monitors.sb2 | Bin 54951 -> 55130 bytes test/integration/monitors.js | 47 ++++++++++++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index 04df0093924..d45fbffe166 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -1028,8 +1028,13 @@ const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extension value: providedArg }; - if (expectedArg.fieldName === 'CURRENTMENU' && providedArg === 'day of week') { - activeBlock.fields[expectedArg.fieldName].value = 'DAYOFWEEK'; + if (expectedArg.fieldName === 'CURRENTMENU') { + // In 3.0, the field value of the `sensing_current` block + // is in all caps. + activeBlock.fields[expectedArg.fieldName].value = providedArg.toUpperCase(); + if (providedArg === 'day of week') { + activeBlock.fields[expectedArg.fieldName].value = 'DAYOFWEEK'; + } } if (expectedArg.fieldName === 'VARIABLE') { diff --git a/src/util/get-monitor-id.js b/src/util/get-monitor-id.js index ada1e7c7090..8582db23184 100644 --- a/src/util/get-monitor-id.js +++ b/src/util/get-monitor-id.js @@ -12,7 +12,20 @@ const getMonitorIdForBlockWithArgs = function (id, fields) { let fieldString = ''; for (const fieldKey in fields) { - fieldString += `_${fields[fieldKey].value}`; + let fieldValue = fields[fieldKey].value; + if (fieldKey === 'CURRENTMENU') { + // The 'sensing_current' block has field values in all caps. + // However, when importing from scratch 2.0, these + // could have gotten imported as lower case field values. + // Normalize the field value here so that we don't ever + // end up with a different monitor ID representing the same + // block configuration + // Note: we are not doing this for every block field that comes into + // this function so as not to make the faulty assumption that block + // field values coming in would be unique after being made lower case + fieldValue = fieldValue.toLowerCase(); + } + fieldString += `_${fieldValue}`; } return `${id}${fieldString}`; }; diff --git a/test/fixtures/monitors.sb2 b/test/fixtures/monitors.sb2 index d4117a83ca2667f2e7173f659ce40673ee1c3124..2b9ede37694c59364eef883646987904c4ebb05d 100644 GIT binary patch delta 1599 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 Rx^!u>?R9ZB)vF+P0svb3S$_Zk diff --git a/test/integration/monitors.js b/test/integration/monitors.js index bf273a4892c..dc9a9e9e46c 100644 --- a/test/integration/monitors.js +++ b/test/integration/monitors.js @@ -17,10 +17,10 @@ test('importing sb2 project with monitors', t => { // All monitors should create threads that finish during the step and // are revoved from runtime.threads. t.equal(threads.length, 0); - t.equal(vm.runtime._lastStepDoneThreads.length, 5); + t.equal(vm.runtime._lastStepDoneThreads.length, 8); // There should be one additional hidden monitor that is in the monitorState but // does not start a thread. - t.equal(vm.runtime._monitorState.size, 6); + t.equal(vm.runtime._monitorState.size, 9); const stage = vm.runtime.targets[0]; const target = vm.runtime.targets[1]; @@ -56,8 +56,8 @@ test('importing sb2 project with monitors', t => { t.equal(monitorRecord.opcode, 'data_listcontents'); t.equal(monitorRecord.mode, 'list'); t.equal(monitorRecord.visible, true); - t.equal(monitorRecord.width, 102); // Make sure these are imported from lists. - t.equal(monitorRecord.height, 202); + t.equal(monitorRecord.width, 104); // Make sure these are imported from lists. + t.equal(monitorRecord.height, 204); // Backdrop name monitor is visible, not sprite specific // should get imported with id that references the name parameter @@ -77,6 +77,45 @@ test('importing sb2 project with monitors', t => { t.equal(monitorRecord.spriteName, 'Sprite1'); t.equal(monitorRecord.targetId, target.id); + + let monitorId; + let monitorBlock; + + // The monitor IDs for the sensing_current block should be unique + // to the parameter that is selected on the block being monitored. + // The paramater portion of the id should be lowercase even + // though the field value on the block is uppercase. + + monitorId = 'current_date'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + + monitorId = 'current_minute'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + + monitorId = 'current_dayofweek'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + t.end(); process.nextTick(process.exit); }); From 7ea310a194eab1ff61775dee8585f6f97a1f22cc Mon Sep 17 00:00:00 2001 From: Karishma Chadha Date: Thu, 8 Nov 2018 14:43:07 -0500 Subject: [PATCH 5/5] Fix typo in comment --- src/engine/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/blocks.js b/src/engine/blocks.js index 4267c76e338..00cc5176131 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -585,7 +585,7 @@ class Blocks { // Note: we're not just constantly creating a longer and longer id everytime we check // the checkbox because we're using the id of the block in the flyout as the base - // check if a block withl the new id already exists, otherwise create + // check if a block with the new id already exists, otherwise create let newBlock = optRuntime.monitorBlocks.getBlock(newId); if (!newBlock) { newBlock = JSON.parse(JSON.stringify(block));