scratch-vm/src/blocks/scratch3_procedures.js
2018-10-23 15:14:31 -04:00

75 lines
2.4 KiB
JavaScript

class Scratch3ProcedureBlocks {
constructor (runtime) {
/**
* The runtime instantiating this block package.
* @type {Runtime}
*/
this.runtime = runtime;
}
/**
* Retrieve the block primitives implemented by this package.
* @return {object.<string, Function>} Mapping of opcode to Function.
*/
getPrimitives () {
return {
procedures_definition: this.definition,
procedures_call: this.call,
argument_reporter_string_number: this.argumentReporterStringNumber,
argument_reporter_boolean: this.argumentReporterBoolean
};
}
definition () {
// No-op: execute the blocks.
}
call (args, util) {
if (!util.stackFrame.executed) {
const procedureCode = args.mutation.proccode;
const paramNamesIdsAndDefaults = util.getProcedureParamNamesIdsAndDefaults(procedureCode);
// If null, procedure could not be found, which can happen if custom
// block is dragged between sprites without the definition.
// Match Scratch 2.0 behavior and noop.
if (paramNamesIdsAndDefaults === null) {
return;
}
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
for (let i = 0; i < paramIds.length; i++) {
if (args.hasOwnProperty(paramIds[i])) {
util.pushParam(paramNames[i], args[paramIds[i]]);
} else {
util.pushParam(paramNames[i], paramDefaults[i]);
}
}
util.stackFrame.executed = true;
util.startProcedure(procedureCode);
}
}
argumentReporterStringNumber (args, util) {
const value = util.getParam(args.VALUE);
if (value === null) {
// When the parameter is not found in the most recent procedure
// call, the default is always 0.
return 0;
}
return value;
}
argumentReporterBoolean (args, util) {
const value = util.getParam(args.VALUE);
if (value === null) {
// When the parameter is not found in the most recent procedure
// call, the default is always 0.
return 0;
}
return value;
}
}
module.exports = Scratch3ProcedureBlocks;