Adding support for blocks to be plugged into the input of broadcast blocks. SB2 Import to come.

This commit is contained in:
Karishma Chadha 2017-12-08 12:19:11 -05:00
parent 2817975e18
commit 413d113dda
3 changed files with 67 additions and 6 deletions

View file

@ -55,9 +55,27 @@ class Scratch3EventBlocks {
return false;
}
/**
* Helper function to process broadcast block input (whether it's
* input from the dropdown menu or from a plugged in input block)
* @param {object} args The given arguments for the broadcast blocks
* @param {object} util The utility associated with this block.
* @return {?Variable} The broadcast message variable that matches
* the provided input.
*/
processBroadcastInput_ (args, util) {
let broadcastInput;
if (args.BROADCAST_OPTION) {
broadcastInput = util.runtime.getTargetForStage().lookupBroadcastMsg(
args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name);
} else {
broadcastInput = util.runtime.getTargetForStage().lookupBroadcastByInputValue(args.BROADCAST_INPUT.name);
}
return broadcastInput;
}
broadcast (args, util) {
const broadcastVar = util.runtime.getTargetForStage().lookupBroadcastMsg(
args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name);
const broadcastVar = this.processBroadcastInput_(args, util);
if (broadcastVar) {
const broadcastOption = broadcastVar.name;
util.startHats('event_whenbroadcastreceived', {
@ -67,8 +85,7 @@ class Scratch3EventBlocks {
}
broadcastAndWait (args, util) {
const broadcastVar = util.runtime.getTargetForStage().lookupBroadcastMsg(
args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name);
const broadcastVar = this.processBroadcastInput_(args, util);
if (broadcastVar) {
const broadcastOption = broadcastVar.name;
// Have we run before, starting threads?

View file

@ -2,6 +2,7 @@ const BlockUtility = require('./block-utility');
const log = require('../util/log');
const Thread = require('./thread');
const {Map} = require('immutable');
const cast = require('../util/cast');
/**
* Single BlockUtility instance reused by execute for every pritimive ran.
@ -211,7 +212,33 @@ const execute = function (sequencer, thread) {
currentStackFrame.waitingReporter = null;
thread.popStack();
}
argValues[inputName] = currentStackFrame.reported[inputName];
const inputValue = currentStackFrame.reported[inputName];
if (inputName === 'BROADCAST_INPUT') {
const broadcastInput = inputs[inputName];
// Check if something is plugged into the broadcast block, or
// if the shadow dropdown menu is being used.
// Differentiate between these two cases by giving argValues
// a 'BROADCAST_INPUT' field or a 'BROADCAST_OPTION' field
// respectively.
if (broadcastInput.block === broadcastInput.shadow) {
// Shadow dropdown menu is being used.
// Get the appropriate information out of it.
const shadow = blockContainer.getBlock(broadcastInput.shadow);
const broadcastField = shadow.fields.BROADCAST_OPTION;
argValues.BROADCAST_OPTION = {
id: broadcastField.id,
name: broadcastField.value
};
} else {
// Something is plugged into the broadcast input.
// Cast it to a string. We don't need an id here.
argValues.BROADCAST_INPUT = {
name: cast.toString(inputValue)
};
}
} else {
argValues[inputName] = inputValue;
}
}
// Add any mutation to args (e.g., for procedures).

View file

@ -115,6 +115,23 @@ class Target extends EventEmitter {
}
}
/**
* Look up a broadcast message with the given name and return the variable
* if it exists. Does not create a new broadcast message variable if
* it doesn't exist.
* @param {string} name Name of the variable.
* @return {?Variable} Variable object.
*/
lookupBroadcastByInputValue (name) {
const vars = this.variables;
for (const propName in vars) {
if ((vars[propName].type === Variable.BROADCAST_MESSAGE_TYPE) &&
(vars[propName].name.toLowerCase() === name.toLowerCase())) {
return vars[propName];
}
}
}
/**
* Look up a variable object.
* Search begins for local variables; then look for globals.
@ -141,7 +158,7 @@ class Target extends EventEmitter {
* Search begins for local lists; then look for globals.
* @param {!string} id Id of the list.
* @param {!string} name Name of the list.
* @return {!List} List object.
* @return {!Varible} Variable object representing the found/created list.
*/
lookupOrCreateList (id, name) {
const list = this.lookupVariableById(id);