Merge pull request #845 from kchadha/broadcast-msg-extra-create-bugfix

Broadcast Msg Bugfix
This commit is contained in:
Paul Kaplan 2017-12-05 15:38:12 -05:00 committed by GitHub
commit e6bd474720
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 48 deletions

View file

@ -56,36 +56,40 @@ class Scratch3EventBlocks {
} }
broadcast (args, util) { broadcast (args, util) {
const broadcastVar = util.runtime.getTargetForStage().lookupOrCreateBroadcastMsg( const broadcastVar = util.runtime.getTargetForStage().lookupBroadcastMsg(
args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name); args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name);
const broadcastOption = broadcastVar.name; if (broadcastVar) {
util.startHats('event_whenbroadcastreceived', { const broadcastOption = broadcastVar.name;
BROADCAST_OPTION: broadcastOption util.startHats('event_whenbroadcastreceived', {
}); BROADCAST_OPTION: broadcastOption
});
}
} }
broadcastAndWait (args, util) { broadcastAndWait (args, util) {
const broadcastVar = util.runtime.getTargetForStage().lookupOrCreateBroadcastMsg( const broadcastVar = util.runtime.getTargetForStage().lookupBroadcastMsg(
args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name); args.BROADCAST_OPTION.id, args.BROADCAST_OPTION.name);
const broadcastOption = broadcastVar.name; if (broadcastVar) {
// Have we run before, starting threads? const broadcastOption = broadcastVar.name;
if (!util.stackFrame.startedThreads) { // Have we run before, starting threads?
// No - start hats for this broadcast. if (!util.stackFrame.startedThreads) {
util.stackFrame.startedThreads = util.startHats( // No - start hats for this broadcast.
'event_whenbroadcastreceived', { util.stackFrame.startedThreads = util.startHats(
BROADCAST_OPTION: broadcastOption 'event_whenbroadcastreceived', {
BROADCAST_OPTION: broadcastOption
}
);
if (util.stackFrame.startedThreads.length === 0) {
// Nothing was started.
return;
} }
);
if (util.stackFrame.startedThreads.length === 0) {
// Nothing was started.
return;
} }
} // We've run before; check if the wait is still going on.
// We've run before; check if the wait is still going on. const instance = this;
const instance = this; const waiting = util.stackFrame.startedThreads.some(thread => instance.runtime.isActiveThread(thread));
const waiting = util.stackFrame.startedThreads.some(thread => instance.runtime.isActiveThread(thread)); if (waiting) {
if (waiting) { util.yield();
util.yield(); }
} }
} }
} }

View file

@ -4,6 +4,7 @@ const Blocks = require('./blocks');
const Variable = require('../engine/variable'); const Variable = require('../engine/variable');
const uid = require('../util/uid'); const uid = require('../util/uid');
const {Map} = require('immutable'); const {Map} = require('immutable');
const log = require('../util/log');
/** /**
* @fileoverview * @fileoverview
@ -93,19 +94,25 @@ class Target extends EventEmitter {
} }
/** /**
* Look up a broadcast message object, and create it if one doesn't exist. * Look up a broadcast message object with the given id and return it
* if it exists.
* @param {string} id Id of the variable. * @param {string} id Id of the variable.
* @param {string} name Name of the variable. * @param {string} name Name of the variable.
* @return {!Variable} Variable object. * @return {!Variable} Variable object.
*/ */
lookupOrCreateBroadcastMsg (id, name) { lookupBroadcastMsg (id, name) {
const broadcastMsg = this.lookupVariableById(id); const broadcastMsg = this.lookupVariableById(id);
if (broadcastMsg) return broadcastMsg; if (broadcastMsg) {
// No variable with this name exists - create it locally. if (broadcastMsg.name !== name) {
const newBroadcastMsg = new Variable(id, name, log.error(`Found broadcast message with id: ${id}, but` +
Variable.BROADCAST_MESSAGE_TYPE, false); `its name, ${broadcastMsg.name} did not match expected name ${name}.`);
this.variables[id] = newBroadcastMsg; }
return newBroadcastMsg; if (broadcastMsg.type !== Variable.BROADCAST_MESSAGE_TYPE) {
log.error(`Found variable with id: ${id}, but its type ${broadcastMsg.type}` +
`did not match expected type ${Variable.BROADCAST_MESSAGE_TYPE}`);
}
return broadcastMsg;
}
} }
/** /**

View file

@ -6,6 +6,7 @@ const Event = require('../../src/blocks/scratch3_event');
const Runtime = require('../../src/engine/runtime'); const Runtime = require('../../src/engine/runtime');
const Target = require('../../src/engine/target'); const Target = require('../../src/engine/target');
const Thread = require('../../src/engine/thread'); const Thread = require('../../src/engine/thread');
const Variable = require('../../src/engine/variable');
test('#760 - broadcastAndWait', t => { test('#760 - broadcastAndWait', t => {
const broadcastAndWaitBlock = { const broadcastAndWaitBlock = {
@ -52,6 +53,7 @@ test('#760 - broadcastAndWait', t => {
b.createBlock(receiveMessageBlock); b.createBlock(receiveMessageBlock);
const tgt = new Target(rt, b); const tgt = new Target(rt, b);
tgt.isStage = true; tgt.isStage = true;
tgt.createVariable('testBroadcastID', 'message', Variable.BROADCAST_MESSAGE_TYPE);
rt.targets.push(tgt); rt.targets.push(tgt);
let th = rt._pushThread('broadcastAndWaitBlock', t); let th = rt._pushThread('broadcastAndWaitBlock', t);
@ -67,12 +69,12 @@ test('#760 - broadcastAndWait', t => {
// yields when some thread is active // yields when some thread is active
t.strictEqual(th.status, Thread.STATUS_YIELD); t.strictEqual(th.status, Thread.STATUS_YIELD);
th.status = Thread.STATUS_RUNNING; th.status = Thread.STATUS_RUNNING;
e.broadcastAndWait({BROADCAST_OPTION: 'message'}, util); e.broadcastAndWait({BROADCAST_OPTION: {id: 'testBroadcastID', name: 'message'}}, util);
t.strictEqual(th.status, Thread.STATUS_YIELD); t.strictEqual(th.status, Thread.STATUS_YIELD);
// does not yield once all threads are done // does not yield once all threads are done
th.status = Thread.STATUS_RUNNING; th.status = Thread.STATUS_RUNNING;
rt.threads[1].status = Thread.STATUS_DONE; rt.threads[1].status = Thread.STATUS_DONE;
e.broadcastAndWait({BROADCAST_OPTION: 'message'}, util); e.broadcastAndWait({BROADCAST_OPTION: {id: 'testBroadcastID', name: 'message'}}, util);
t.strictEqual(th.status, Thread.STATUS_RUNNING); t.strictEqual(th.status, Thread.STATUS_RUNNING);
// restarts done threads that are in runtime threads // restarts done threads that are in runtime threads

View file

@ -174,20 +174,7 @@ test('lookupOrCreateList returns list if one with given id exists', t => {
t.end(); t.end();
}); });
test('lookupOrCreateBroadcastMsg creates a var if one does not exist', t => { test('lookupBroadcastMsg returns the var with given id if exists', t => {
const target = new Target();
const variables = target.variables;
t.equal(Object.keys(variables).length, 0);
const broadcastVar = target.lookupOrCreateBroadcastMsg('foo', 'bar');
t.equal(Object.keys(variables).length, 1);
t.equal(broadcastVar.id, 'foo');
t.equal(broadcastVar.name, 'bar');
t.end();
});
test('lookupOrCreateBroadcastMsg returns the var with given id if exists', t => {
const target = new Target(); const target = new Target();
const variables = target.variables; const variables = target.variables;
@ -195,7 +182,7 @@ test('lookupOrCreateBroadcastMsg returns the var with given id if exists', t =>
target.createVariable('foo', 'bar', Variable.BROADCAST_MESSAGE_TYPE); target.createVariable('foo', 'bar', Variable.BROADCAST_MESSAGE_TYPE);
t.equal(Object.keys(variables).length, 1); t.equal(Object.keys(variables).length, 1);
const broadcastMsg = target.lookupOrCreateBroadcastMsg('foo', 'bar'); const broadcastMsg = target.lookupBroadcastMsg('foo', 'bar');
t.equal(Object.keys(variables).length, 1); t.equal(Object.keys(variables).length, 1);
t.equal(broadcastMsg.id, 'foo'); t.equal(broadcastMsg.id, 'foo');
t.equal(broadcastMsg.name, 'bar'); t.equal(broadcastMsg.name, 'bar');