From c63747e61bce51c0ad78ddc6f35f84d90230f60d Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Mon, 20 Jun 2016 15:04:28 -0400 Subject: [PATCH] Move stepping logic for reporters to sequencer --- src/engine/execute.js | 23 ++++++----------------- src/engine/sequencer.js | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/engine/execute.js b/src/engine/execute.js index 2cee0a1c9..6e1962808 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -48,24 +48,13 @@ var execute = function (sequencer, thread) { // Is there no value for this input waiting in the stack frame? if (typeof currentStackFrame.reported[inputName] === 'undefined') { // If there's not, we need to evaluate the block. - // Push to the stack to evaluate this input. - thread.pushStack(inputBlockId); - if (DEBUG_BLOCK_CALLS) { - console.time('Reporter evaluation'); - } - runtime.glowBlock(inputBlockId, true); - // Save name of input for `Thread.pushReportedValue`. - currentStackFrame.waitingReporter = inputName; - execute(sequencer, thread); - if (thread.status === Thread.STATUS_YIELD) { - // Reporter yielded; don't pop stack and wait for it to unyield. - // The value will be populated once the reporter unyields, - // and passed up to the currentStackFrame on next execution. + var reporterYielded = ( + sequencer.stepToReporter(thread, inputBlockId, inputName) + ); + // If the reporter yielded, return immediately; + // it needs time to finish and report its value. + if (reporterYielded) { return; - } else { - // Reporter finished right away; pop the stack. - runtime.glowBlock(inputBlockId, false); - thread.popStack(); } } argValues[inputName] = currentStackFrame.reported[inputName]; diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js index e82d4054c..27e3b9996 100644 --- a/src/engine/sequencer.js +++ b/src/engine/sequencer.js @@ -127,6 +127,33 @@ Sequencer.prototype.stepToSubstack = function (thread, substackNum) { } }; +/** + * Step a thread into an input reporter, and manage its status appropriately. + * @param {!Thread} thread Thread object to step to reporter. + * @param {!string} blockId ID of reporter block. + * @param {!string} inputName Name of input on parent block. + * @return {boolean} True if yielded, false if it finished immediately. + */ +Sequencer.prototype.stepToReporter = function (thread, blockId, inputName) { + var currentStackFrame = thread.peekStackFrame(); + // Push to the stack to evaluate the reporter block. + thread.pushStack(blockId); + // Save name of input for `Thread.pushReportedValue`. + currentStackFrame.waitingReporter = inputName; + // Actually execute the block. + this.startThread(thread); + if (thread.status === Thread.STATUS_YIELD) { + // Reporter yielded; caller must wait for it to unyield. + // The value will be populated once the reporter unyields, + // and passed up to the currentStackFrame on next execution. + return true; + } else if (thread.status === Thread.STATUS_DONE) { + // Reporter finished, mark the thread as running. + thread.status = Thread.STATUS_RUNNING; + return false; + } +}; + /** * Finish stepping a thread and proceed it to the next block. * @param {!Thread} thread Thread object to proceed.