mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-08-06 19:41:51 -04:00
Merge pull request #963 from towerofnix/foreach-vm
Implement for-each block
This commit is contained in:
commit
51306e3492
3 changed files with 75 additions and 0 deletions
|
@ -17,6 +17,7 @@ class Scratch3ControlBlocks {
|
||||||
return {
|
return {
|
||||||
control_repeat: this.repeat,
|
control_repeat: this.repeat,
|
||||||
control_repeat_until: this.repeatUntil,
|
control_repeat_until: this.repeatUntil,
|
||||||
|
control_for_each: this.forEach,
|
||||||
control_forever: this.forever,
|
control_forever: this.forever,
|
||||||
control_wait: this.wait,
|
control_wait: this.wait,
|
||||||
control_wait_until: this.waitUntil,
|
control_wait_until: this.waitUntil,
|
||||||
|
@ -61,6 +62,21 @@ class Scratch3ControlBlocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forEach (args, util) {
|
||||||
|
const variable = util.target.lookupOrCreateVariable(
|
||||||
|
args.VARIABLE.id, args.VARIABLE.name);
|
||||||
|
|
||||||
|
if (typeof util.stackFrame.index === 'undefined') {
|
||||||
|
util.stackFrame.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (util.stackFrame.index < Number(args.VALUE)) {
|
||||||
|
util.stackFrame.index++;
|
||||||
|
variable.value = util.stackFrame.index;
|
||||||
|
util.startBranch(1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
waitUntil (args, util) {
|
waitUntil (args, util) {
|
||||||
const condition = Cast.toBoolean(args.CONDITION);
|
const condition = Cast.toBoolean(args.CONDITION);
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
|
|
|
@ -768,6 +768,24 @@ const specMap = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
'doForLoop': {
|
||||||
|
opcode: 'control_for_each',
|
||||||
|
argMap: [
|
||||||
|
{
|
||||||
|
type: 'field',
|
||||||
|
fieldName: 'VARIABLE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
inputOp: 'text',
|
||||||
|
inputName: 'VALUE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
inputName: 'SUBSTACK'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
'stopScripts': {
|
'stopScripts': {
|
||||||
opcode: 'control_stop',
|
opcode: 'control_stop',
|
||||||
argMap: [
|
argMap: [
|
||||||
|
|
|
@ -52,6 +52,47 @@ test('repeatUntil', t => {
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('forEach', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const c = new Control(rt);
|
||||||
|
|
||||||
|
const variableValues = [];
|
||||||
|
const variable = {value: 0};
|
||||||
|
let value;
|
||||||
|
const util = {
|
||||||
|
stackFrame: Object.create(null),
|
||||||
|
target: {
|
||||||
|
lookupOrCreateVariable: function () {
|
||||||
|
return variable;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startBranch: function () {
|
||||||
|
variableValues.push(variable.value);
|
||||||
|
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// for each (variable) in "5"
|
||||||
|
// ..should yield variable values 1, 2, 3, 4, 5
|
||||||
|
util.stackFrame = Object.create(null);
|
||||||
|
variableValues.splice(0);
|
||||||
|
variable.value = 0;
|
||||||
|
value = '5';
|
||||||
|
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||||
|
t.deepEqual(variableValues, [1, 2, 3, 4, 5]);
|
||||||
|
|
||||||
|
// for each (variable) in 4
|
||||||
|
// ..should yield variable values 1, 2, 3, 4
|
||||||
|
util.stackFrame = Object.create(null);
|
||||||
|
variableValues.splice(0);
|
||||||
|
variable.value = 0;
|
||||||
|
value = 4;
|
||||||
|
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||||
|
t.deepEqual(variableValues, [1, 2, 3, 4]);
|
||||||
|
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
||||||
test('forever', t => {
|
test('forever', t => {
|
||||||
const rt = new Runtime();
|
const rt = new Runtime();
|
||||||
const c = new Control(rt);
|
const c = new Control(rt);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue