From 4deee071b2a2d34fee3a6bb97aefe549b847b35d Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Thu, 10 Nov 2016 15:05:49 -0500 Subject: [PATCH] Don't copy threads in step; stable restartThread (#331) --- src/engine/runtime.js | 21 ++++++++++++++++++++- src/engine/sequencer.js | 6 ++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 4fe871a6..36722a45 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -329,6 +329,24 @@ Runtime.prototype._removeThread = function (thread) { } }; +/** + * Restart a thread in place, maintaining its position in the list of threads. + * This is used by `startHats` to and is necessary to ensure 2.0-like execution order. + * Test project: https://scratch.mit.edu/projects/130183108/ + * @param {!Thread} thread Thread object to restart. + */ +Runtime.prototype._restartThread = function (thread) { + var newThread = new Thread(thread.topBlock); + newThread.target = thread.target; + newThread.pushStack(thread.topBlock); + var i = this.threads.indexOf(thread); + if (i > -1) { + this.threads[i] = newThread; + } else { + this.threads.push(thread); + } +}; + /** * Return whether a thread is currently active/running. * @param {?Thread} thread Thread object to check. @@ -422,7 +440,8 @@ Runtime.prototype.startHats = function (requestedHatOpcode, for (var i = 0; i < instance.threads.length; i++) { if (instance.threads[i].topBlock === topBlockId && instance.threads[i].target === target) { - instance._removeThread(instance.threads[i]); + instance._restartThread(instance.threads[i]); + return; } } } else { diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js index c777949b..8c732ca9 100644 --- a/src/engine/sequencer.js +++ b/src/engine/sequencer.js @@ -45,11 +45,9 @@ Sequencer.prototype.stepThreads = function () { this.timer.timeElapsed() < WORK_TIME && (this.runtime.turboMode || !this.runtime.redrawRequested)) { numActiveThreads = 0; - // Inline copy of the threads, updated on each step. - var threadsCopy = this.runtime.threads.slice(); // Attempt to run each thread one time. - for (var i = 0; i < threadsCopy.length; i++) { - var activeThread = threadsCopy[i]; + for (var i = 0; i < this.runtime.threads.length; i++) { + var activeThread = this.runtime.threads[i]; if (activeThread.stack.length === 0 || activeThread.status === Thread.STATUS_DONE) { // Finished with this thread.