mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
Merge pull request #845 from kchadha/broadcast-msg-extra-create-bugfix
Broadcast Msg Bugfix
This commit is contained in:
commit
e6bd474720
4 changed files with 48 additions and 48 deletions
|
@ -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();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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');
|
||||||
|
|
Loading…
Reference in a new issue