mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 06:23:37 -05:00
Merge pull request #1631 from mzgoddard/stop-other-asks
Stop other asks
This commit is contained in:
commit
23f6346045
3 changed files with 112 additions and 0 deletions
|
@ -42,6 +42,7 @@ class Scratch3SensingBlocks {
|
||||||
this.runtime.on('ANSWER', this._onAnswer.bind(this));
|
this.runtime.on('ANSWER', this._onAnswer.bind(this));
|
||||||
this.runtime.on('PROJECT_START', this._resetAnswer.bind(this));
|
this.runtime.on('PROJECT_START', this._resetAnswer.bind(this));
|
||||||
this.runtime.on('PROJECT_STOP_ALL', this._clearAllQuestions.bind(this));
|
this.runtime.on('PROJECT_STOP_ALL', this._clearAllQuestions.bind(this));
|
||||||
|
this.runtime.on('STOP_FOR_TARGET', this._clearTargetQuestions.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,6 +135,21 @@ class Scratch3SensingBlocks {
|
||||||
this.runtime.emit('QUESTION', null);
|
this.runtime.emit('QUESTION', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clearTargetQuestions (stopTarget) {
|
||||||
|
const currentlyAsking = this._questionList.length > 0 && this._questionList[0][2] === stopTarget;
|
||||||
|
this._questionList = this._questionList.filter(question => (
|
||||||
|
question[2] !== stopTarget
|
||||||
|
));
|
||||||
|
|
||||||
|
if (currentlyAsking) {
|
||||||
|
if (this._questionList.length > 0) {
|
||||||
|
this._askNextQuestion();
|
||||||
|
} else {
|
||||||
|
this.runtime.emit('QUESTION', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
askAndWait (args, util) {
|
askAndWait (args, util) {
|
||||||
const _target = util.target;
|
const _target = util.target;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
|
@ -383,6 +383,15 @@ class Runtime extends EventEmitter {
|
||||||
return 'PROJECT_STOP_ALL';
|
return 'PROJECT_STOP_ALL';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event name for target being stopped by a stop for target call.
|
||||||
|
* Used by blocks that need to stop individual targets.
|
||||||
|
* @const {string}
|
||||||
|
*/
|
||||||
|
static get STOP_FOR_TARGET () {
|
||||||
|
return 'STOP_FOR_TARGET';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event name for visual value report.
|
* Event name for visual value report.
|
||||||
* @const {string}
|
* @const {string}
|
||||||
|
@ -1450,6 +1459,9 @@ class Runtime extends EventEmitter {
|
||||||
* @param {Thread=} optThreadException Optional thread to skip.
|
* @param {Thread=} optThreadException Optional thread to skip.
|
||||||
*/
|
*/
|
||||||
stopForTarget (target, optThreadException) {
|
stopForTarget (target, optThreadException) {
|
||||||
|
// Emit stop event to allow blocks to clean up any state.
|
||||||
|
this.emit(Runtime.STOP_FOR_TARGET, target, optThreadException);
|
||||||
|
|
||||||
// Stop any threads on the target.
|
// Stop any threads on the target.
|
||||||
for (let i = 0; i < this.threads.length; i++) {
|
for (let i = 0; i < this.threads.length; i++) {
|
||||||
if (this.threads[i] === optThreadException) {
|
if (this.threads[i] === optThreadException) {
|
||||||
|
|
|
@ -37,6 +37,90 @@ test('ask and answer with a hidden target', t => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('ask and stop all dismisses question', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const s = new Sensing(rt);
|
||||||
|
const util = {target: {visible: false}};
|
||||||
|
|
||||||
|
const expectedQuestion = 'a question';
|
||||||
|
|
||||||
|
let call = 0;
|
||||||
|
|
||||||
|
rt.addListener('QUESTION', question => {
|
||||||
|
if (call === 0) {
|
||||||
|
// (2) Assert the question was passed.
|
||||||
|
t.strictEqual(question, expectedQuestion);
|
||||||
|
} else if (call === 1) {
|
||||||
|
// (4) Assert the question was dismissed.
|
||||||
|
t.strictEqual(question, null);
|
||||||
|
t.end();
|
||||||
|
}
|
||||||
|
call += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// (1) Emit the question.
|
||||||
|
s.askAndWait({QUESTION: expectedQuestion}, util);
|
||||||
|
// (3) Emit the stop all event.
|
||||||
|
rt.stopAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ask and stop other scripts dismisses if it is the last question', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const s = new Sensing(rt);
|
||||||
|
const util = {target: {visible: false}, thread: {}};
|
||||||
|
|
||||||
|
const expectedQuestion = 'a question';
|
||||||
|
|
||||||
|
let call = 0;
|
||||||
|
|
||||||
|
rt.addListener('QUESTION', question => {
|
||||||
|
if (call === 0) {
|
||||||
|
// (2) Assert the question was passed.
|
||||||
|
t.strictEqual(question, expectedQuestion);
|
||||||
|
} else if (call === 1) {
|
||||||
|
// (4) Assert the question was dismissed.
|
||||||
|
t.strictEqual(question, null);
|
||||||
|
t.end();
|
||||||
|
}
|
||||||
|
call += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// (1) Emit the questions.
|
||||||
|
s.askAndWait({QUESTION: expectedQuestion}, util);
|
||||||
|
// (3) Emit the stop for target event.
|
||||||
|
rt.stopForTarget(util.target, util.thread);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ask and stop other scripts asks next question', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const s = new Sensing(rt);
|
||||||
|
const util = {target: {visible: false}, thread: {}};
|
||||||
|
const util2 = {target: {visible: false}, thread: {}};
|
||||||
|
|
||||||
|
const expectedQuestion = 'a question';
|
||||||
|
const nextQuestion = 'a followup';
|
||||||
|
|
||||||
|
let call = 0;
|
||||||
|
|
||||||
|
rt.addListener('QUESTION', question => {
|
||||||
|
if (call === 0) {
|
||||||
|
// (2) Assert the question was passed.
|
||||||
|
t.strictEqual(question, expectedQuestion);
|
||||||
|
} else if (call === 1) {
|
||||||
|
// (4) Assert the next question was passed.
|
||||||
|
t.strictEqual(question, nextQuestion);
|
||||||
|
t.end();
|
||||||
|
}
|
||||||
|
call += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// (1) Emit the questions.
|
||||||
|
s.askAndWait({QUESTION: expectedQuestion}, util);
|
||||||
|
s.askAndWait({QUESTION: nextQuestion}, util2);
|
||||||
|
// (3) Emit the stop for target event.
|
||||||
|
rt.stopForTarget(util.target, util.thread);
|
||||||
|
});
|
||||||
|
|
||||||
test('ask and answer with a visible target', t => {
|
test('ask and answer with a visible target', t => {
|
||||||
const rt = new Runtime();
|
const rt = new Runtime();
|
||||||
const s = new Sensing(rt);
|
const s = new Sensing(rt);
|
||||||
|
|
Loading…
Reference in a new issue