mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-24 06:52:40 -05:00
Merge pull request #698 from paulkaplan/update-custom-procedures
Changing parsing of custom procedures for new style
This commit is contained in:
commit
8ac348d931
5 changed files with 59 additions and 16 deletions
|
@ -152,10 +152,12 @@ class Blocks {
|
||||||
for (const id in this._blocks) {
|
for (const id in this._blocks) {
|
||||||
if (!this._blocks.hasOwnProperty(id)) continue;
|
if (!this._blocks.hasOwnProperty(id)) continue;
|
||||||
const block = this._blocks[id];
|
const block = this._blocks[id];
|
||||||
if ((block.opcode === 'procedures_defnoreturn' ||
|
if (block.opcode === 'procedures_defnoreturn' ||
|
||||||
block.opcode === 'procedures_defreturn') &&
|
block.opcode === 'procedures_defreturn') {
|
||||||
block.mutation.proccode === name) {
|
const internal = this._getCustomBlockInternal(block);
|
||||||
return id;
|
if (internal && internal.mutation.proccode === name) {
|
||||||
|
return id; // The outer define block id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -170,8 +172,7 @@ class Blocks {
|
||||||
for (const id in this._blocks) {
|
for (const id in this._blocks) {
|
||||||
if (!this._blocks.hasOwnProperty(id)) continue;
|
if (!this._blocks.hasOwnProperty(id)) continue;
|
||||||
const block = this._blocks[id];
|
const block = this._blocks[id];
|
||||||
if ((block.opcode === 'procedures_defnoreturn' ||
|
if (block.opcode === 'procedures_callnoreturn_internal' &&
|
||||||
block.opcode === 'procedures_defreturn') &&
|
|
||||||
block.mutation.proccode === name) {
|
block.mutation.proccode === name) {
|
||||||
return JSON.parse(block.mutation.argumentnames);
|
return JSON.parse(block.mutation.argumentnames);
|
||||||
}
|
}
|
||||||
|
@ -547,6 +548,17 @@ class Blocks {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to get the corresponding internal procedure definition block
|
||||||
|
* @param {!object} defineBlock Outer define block.
|
||||||
|
* @return {!object} internal definition block which has the mutation.
|
||||||
|
*/
|
||||||
|
_getCustomBlockInternal (defineBlock) {
|
||||||
|
if (defineBlock.inputs && defineBlock.inputs.custom_block) {
|
||||||
|
return this._blocks[defineBlock.inputs.custom_block.block];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to add a stack to `this._scripts`.
|
* Helper to add a stack to `this._scripts`.
|
||||||
* @param {?string} topBlockId ID of block that starts the script.
|
* @param {?string} topBlockId ID of block that starts the script.
|
||||||
|
|
|
@ -148,6 +148,8 @@ const execute = function (sequencer, thread) {
|
||||||
// Recursively evaluate input blocks.
|
// Recursively evaluate input blocks.
|
||||||
for (const inputName in inputs) {
|
for (const inputName in inputs) {
|
||||||
if (!inputs.hasOwnProperty(inputName)) continue;
|
if (!inputs.hasOwnProperty(inputName)) continue;
|
||||||
|
// Do not evaluate the internal custom command block within definition
|
||||||
|
if (inputName === 'custom_block') continue;
|
||||||
const input = inputs[inputName];
|
const input = inputs[inputName];
|
||||||
const inputBlockId = input.block;
|
const inputBlockId = input.block;
|
||||||
// Is there no value for this input waiting in the stack frame?
|
// Is there no value for this input waiting in the stack frame?
|
||||||
|
|
|
@ -225,7 +225,9 @@ class Sequencer {
|
||||||
// Look for warp-mode flag on definition, and set the thread
|
// Look for warp-mode flag on definition, and set the thread
|
||||||
// to warp-mode if needed.
|
// to warp-mode if needed.
|
||||||
const definitionBlock = thread.target.blocks.getBlock(definition);
|
const definitionBlock = thread.target.blocks.getBlock(definition);
|
||||||
const doWarp = definitionBlock.mutation.warp;
|
const innerBlock = thread.target.blocks.getBlock(
|
||||||
|
definitionBlock.inputs.custom_block.block);
|
||||||
|
const doWarp = innerBlock.mutation.warp;
|
||||||
if (doWarp) {
|
if (doWarp) {
|
||||||
thread.peekStackFrame().warpMode = true;
|
thread.peekStackFrame().warpMode = true;
|
||||||
} else if (isRecursive) {
|
} else if (isRecursive) {
|
||||||
|
|
|
@ -481,14 +481,31 @@ const parseBlock = function (sb2block, getVariableId) {
|
||||||
// Mutation for procedure definition:
|
// Mutation for procedure definition:
|
||||||
// store all 2.0 proc data.
|
// store all 2.0 proc data.
|
||||||
const procData = sb2block.slice(1);
|
const procData = sb2block.slice(1);
|
||||||
activeBlock.mutation = {
|
// Create a new block and input metadata.
|
||||||
tagName: 'mutation',
|
const inputUid = uid();
|
||||||
proccode: procData[0], // e.g., "abc %n %b %s"
|
const inputName = 'custom_block';
|
||||||
argumentnames: JSON.stringify(procData[1]), // e.g. ['arg1', 'arg2']
|
activeBlock.inputs[inputName] = {
|
||||||
argumentdefaults: JSON.stringify(procData[2]), // e.g., [1, 'abc']
|
name: inputName,
|
||||||
warp: procData[3], // Warp mode, e.g., true/false.
|
block: inputUid,
|
||||||
children: []
|
shadow: inputUid
|
||||||
};
|
};
|
||||||
|
activeBlock.children = [{
|
||||||
|
id: inputUid,
|
||||||
|
opcode: 'procedures_callnoreturn_internal',
|
||||||
|
inputs: {},
|
||||||
|
fields: {},
|
||||||
|
next: null,
|
||||||
|
shadow: true,
|
||||||
|
children: [],
|
||||||
|
mutation: {
|
||||||
|
tagName: 'mutation',
|
||||||
|
proccode: procData[0], // e.g., "abc %n %b %s"
|
||||||
|
argumentnames: JSON.stringify(procData[1]), // e.g. ['arg1', 'arg2']
|
||||||
|
argumentdefaults: JSON.stringify(procData[2]), // e.g., [1, 'abc']
|
||||||
|
warp: procData[3], // Warp mode, e.g., true/false.
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
}];
|
||||||
} else if (oldOpcode === 'call') {
|
} else if (oldOpcode === 'call') {
|
||||||
// Mutation for procedure call:
|
// Mutation for procedure call:
|
||||||
// string for proc code (e.g., "abc %n %b %s").
|
// string for proc code (e.g., "abc %n %b %s").
|
||||||
|
|
|
@ -153,9 +153,19 @@ test('stepToProcedure', t => {
|
||||||
t.strictEquals(th.peekStack(), expectedBlock);
|
t.strictEquals(th.peekStack(), expectedBlock);
|
||||||
s.stepToProcedure(th, 'faceCode');
|
s.stepToProcedure(th, 'faceCode');
|
||||||
t.strictEquals(th.peekStack(), expectedBlock);
|
t.strictEquals(th.peekStack(), expectedBlock);
|
||||||
s.stepToProcedure(th, 'faceCode');
|
|
||||||
th.target.blocks.getBlock(th.stack[th.stack.length - 4]).mutation.proccode = 'othercode';
|
th.target.blocks.createBlock({
|
||||||
|
id: 'internalId',
|
||||||
|
opcode: 'procedures_callnoreturn_internal',
|
||||||
|
mutation: {
|
||||||
|
proccode: 'othercode'
|
||||||
|
}
|
||||||
|
});
|
||||||
expectedBlock = th.stack[th.stack.length - 4];
|
expectedBlock = th.stack[th.stack.length - 4];
|
||||||
|
th.target.blocks.getBlock(expectedBlock).inputs.custom_block = {
|
||||||
|
type: 'custom_block',
|
||||||
|
block: 'internalId'
|
||||||
|
};
|
||||||
s.stepToProcedure(th, 'othercode');
|
s.stepToProcedure(th, 'othercode');
|
||||||
t.strictEquals(th.peekStack(), expectedBlock);
|
t.strictEquals(th.peekStack(), expectedBlock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue