mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 06:23:37 -05:00
Ask/answer opcode implementation with runtime events.
This commit is contained in:
parent
ef961c5a4b
commit
73ffc6a797
2 changed files with 91 additions and 1 deletions
|
@ -7,6 +7,21 @@ class Scratch3SensingBlocks {
|
||||||
* @type {Runtime}
|
* @type {Runtime}
|
||||||
*/
|
*/
|
||||||
this.runtime = runtime;
|
this.runtime = runtime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "answer" block value.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this._answer = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of queued questions and respective `resolve` callbacks.
|
||||||
|
* @type {!Array}
|
||||||
|
*/
|
||||||
|
this._questionList = [];
|
||||||
|
|
||||||
|
this.runtime.on('ANSWER', this._onAnswer.bind(this));
|
||||||
|
this.runtime.on('PROJECT_STOP_ALL', this._clearAllQuestions.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,10 +43,51 @@ class Scratch3SensingBlocks {
|
||||||
sensing_keypressed: this.getKeyPressed,
|
sensing_keypressed: this.getKeyPressed,
|
||||||
sensing_current: this.current,
|
sensing_current: this.current,
|
||||||
sensing_dayssince2000: this.daysSince2000,
|
sensing_dayssince2000: this.daysSince2000,
|
||||||
sensing_loudness: this.getLoudness
|
sensing_loudness: this.getLoudness,
|
||||||
|
sensing_askandwait: this.askAndWait,
|
||||||
|
sensing_answer: this.getAnswer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onAnswer (answer) {
|
||||||
|
this._answer = answer;
|
||||||
|
const questionObj = this._questionList.shift();
|
||||||
|
if (questionObj) {
|
||||||
|
const resolve = questionObj[1];
|
||||||
|
resolve();
|
||||||
|
this._askNextQuestion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_enqueueAsk (question, resolve) {
|
||||||
|
this._questionList.push([question, resolve]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_askNextQuestion () {
|
||||||
|
if (this._questionList.length > 0) {
|
||||||
|
this.runtime.emit('QUESTION', this._questionList[0][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearAllQuestions () {
|
||||||
|
this._questionList = [];
|
||||||
|
this.runtime.emit('QUESTION', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
askAndWait (args) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const isQuestionAsked = this._questionList.length > 0;
|
||||||
|
this._enqueueAsk(args.QUESTION, resolve);
|
||||||
|
if (!isQuestionAsked) {
|
||||||
|
this._askNextQuestion();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnswer () {
|
||||||
|
return this._answer;
|
||||||
|
}
|
||||||
|
|
||||||
touchingObject (args, util) {
|
touchingObject (args, util) {
|
||||||
const requestedObject = args.TOUCHINGOBJECTMENU;
|
const requestedObject = args.TOUCHINGOBJECTMENU;
|
||||||
if (requestedObject === '_mouse_') {
|
if (requestedObject === '_mouse_') {
|
||||||
|
|
34
test/unit/blocks_sensing.js
Normal file
34
test/unit/blocks_sensing.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
const test = require('tap').test;
|
||||||
|
const Sensing = require('../../src/blocks/scratch3_sensing');
|
||||||
|
const Runtime = require('../../src/engine/runtime');
|
||||||
|
|
||||||
|
test('getPrimitives', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const s = new Sensing(rt);
|
||||||
|
t.type(s.getPrimitives(), 'object');
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ask and answer', t => {
|
||||||
|
const rt = new Runtime();
|
||||||
|
const s = new Sensing(rt);
|
||||||
|
|
||||||
|
const expectedQuestion = 'a question';
|
||||||
|
const expectedAnswer = 'the answer';
|
||||||
|
|
||||||
|
// Test is written out of order because of promises, follow the (#) comments.
|
||||||
|
rt.addListener('QUESTION', question => {
|
||||||
|
// (2) Assert the question is correct, then emit the answer
|
||||||
|
t.strictEqual(question, expectedQuestion);
|
||||||
|
rt.emit('ANSWER', expectedAnswer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// (1) Emit the question.
|
||||||
|
const promise = s.askAndWait({QUESTION: expectedQuestion});
|
||||||
|
|
||||||
|
// (3) Ask block resolves after the answer is emitted.
|
||||||
|
promise.then(() => {
|
||||||
|
t.strictEqual(s.getAnswer(), expectedAnswer);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue