Skip to content

Use script glow status to track whether the project is running #3912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 18 additions & 29 deletions src/engine/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class Runtime extends EventEmitter {
* These will execute on `_editingTarget.`
* @type {!Blocks}
*/
this.flyoutBlocks = new Blocks(this, true /* force no glow */);
this.flyoutBlocks = new Blocks(this, false /* force no glow */);

/**
* Storage container for monitor blocks.
Expand Down Expand Up @@ -248,10 +248,10 @@ class Runtime extends EventEmitter {
this._scriptGlowsPreviousFrame = [];

/**
* Number of non-monitor threads running during the previous frame.
* @type {number}
* Whether the project counted as "running" during the previous frame.
* @type {boolean}
*/
this._nonMonitorThreadCount = 0;
this._projectRanLastFrame = false;

/**
* All threads that finished running and were removed from this.threads
Expand Down Expand Up @@ -2093,11 +2093,16 @@ class Runtime extends EventEmitter {
this.profiler.stop();
}
this._updateGlows(doneThreads);

// Threads count as "running" if a block glowed in the thread this frame.
// This excludes edge-activated hat predicates and monitor blocks.
const threadCountsTowardsRunStatus = thread => thread.requestScriptGlowInFrame &&
thread.blockGlowInFrame !== null;
// Add done threads so that even if a thread finishes within 1 frame, the green
// flag will still indicate that a script ran.
this._emitProjectRunStatus(
this.threads.length + doneThreads.length -
this._getMonitorThreadCount([...this.threads, ...doneThreads]));
const anyThreadsRunning = this.threads.some(threadCountsTowardsRunStatus) ||
doneThreads.some(threadCountsTowardsRunStatus);
this._emitProjectRunStatus(anyThreadsRunning);
// Store threads that completed this iteration for testing and other
// internal purposes.
this._lastStepDoneThreads = doneThreads;
Expand Down Expand Up @@ -2131,20 +2136,6 @@ class Runtime extends EventEmitter {
}
}

/**
* Get the number of threads in the given array that are monitor threads (threads
* that update monitor values, and don't count as running a script).
* @param {!Array.<Thread>} threads The set of threads to look through.
* @return {number} The number of monitor threads in threads.
*/
_getMonitorThreadCount (threads) {
let count = 0;
threads.forEach(thread => {
if (thread.updateMonitor) count++;
});
return count;
}

/**
* Queue monitor blocks to sequencer to be run.
*/
Expand Down Expand Up @@ -2239,19 +2230,17 @@ class Runtime extends EventEmitter {
}

/**
* Emit run start/stop after each tick. Emits when `this.threads.length` goes
* between non-zero and zero
*
* @param {number} nonMonitorThreadCount The new nonMonitorThreadCount
* Emit run start/stop after each tick. Emits when `this.threads.length` goes between non-zero and zero
* @param {boolean} projectRunning Whether the project is running (threads.length > 0)
*/
_emitProjectRunStatus (nonMonitorThreadCount) {
if (this._nonMonitorThreadCount === 0 && nonMonitorThreadCount > 0) {
_emitProjectRunStatus (projectRunning) {
if (!this._projectRanLastFrame && projectRunning) {
this.emit(Runtime.PROJECT_RUN_START);
}
if (this._nonMonitorThreadCount > 0 && nonMonitorThreadCount === 0) {
if (this._projectRanLastFrame && !projectRunning) {
this.emit(Runtime.PROJECT_RUN_STOP);
}
this._nonMonitorThreadCount = nonMonitorThreadCount;
this._projectRanLastFrame = projectRunning;
}

/**
Expand Down