Allow specmap to have methods to branch into multiple sb3 opcodes

This commit is contained in:
Corey Frang 2018-04-05 15:39:16 -04:00
parent 41955913aa
commit 78199c41a5
2 changed files with 51 additions and 20 deletions

View file

@ -447,6 +447,24 @@ const sb2import = function (json, runtime, optForceSprite) {
}));
};
/**
* Given the sb2 block, inspect the specmap for a translation method or object.
* @param {!object} block a sb2 formatted block
* @return {object} specmap block to parse this opcode
*/
const specMapBlock = function (block) {
const opcode = block[0];
const mapped = opcode && specMap[opcode];
if (!mapped) {
log.warn(`Couldn't find SB2 block: ${opcode}`);
return null;
}
if (typeof mapped === 'function') {
return mapped(block);
}
return mapped;
};
/**
* Parse a single SB2 JSON-formatted block and its children.
* @param {!object} sb2block SB2 JSON-formatted block.
@ -456,14 +474,11 @@ const sb2import = function (json, runtime, optForceSprite) {
* @return {object} Scratch VM format block, or null if unsupported object.
*/
const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extensions) {
// First item in block object is the old opcode (e.g., 'forward:').
const oldOpcode = sb2block[0];
// Convert the block using the specMap. See sb2specmap.js.
if (!oldOpcode || !specMap[oldOpcode]) {
log.warn('Couldn\'t find SB2 block: ', oldOpcode);
return null;
const blockMetadata = specMapBlock(sb2block);
if (!blockMetadata) {
return;
}
const blockMetadata = specMap[oldOpcode];
const oldOpcode = sb2block[0];
// If the block is from an extension, record it.
const dotIndex = blockMetadata.opcode.indexOf('.');
if (dotIndex >= 0) {

View file

@ -652,19 +652,35 @@ const specMap = {
}
]
},
'whenSensorGreaterThan': {
opcode: 'event_whengreaterthan',
argMap: [
{
type: 'field',
fieldName: 'WHENGREATERTHANMENU'
},
{
type: 'input',
inputOp: 'math_number',
inputName: 'VALUE'
}
]
'whenSensorGreaterThan': ([, sensor]) => {
if (sensor === 'video motion') {
return {
opcode: 'videoSensing.whenMotionGreaterThan',
argMap: [
// skip the first arg, since we converted to a video specific sensing block
{},
{
type: 'input',
inputOp: 'math_number',
inputName: 'REFERENCE'
}
]
};
}
return {
opcode: 'event_whengreaterthan',
argMap: [
{
type: 'field',
fieldName: 'WHENGREATERTHANMENU'
},
{
type: 'input',
inputOp: 'math_number',
inputName: 'VALUE'
}
]
};
},
'whenIReceive': {
opcode: 'event_whenbroadcastreceived',