Skip to content

Commit

Permalink
Finalize setStatus and finish setPause
Browse files Browse the repository at this point in the history
  • Loading branch information
AshimeeAlt committed Nov 6, 2024
1 parent 23d948d commit 72f43c9
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 24 deletions.
10 changes: 5 additions & 5 deletions src/compiler/jsexecute.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ runtimeFunctions.waitThreads = `const waitThreads = function*(threads) {
}
}
if (allWaiting) {
thread.status = 3; // STATUS_YIELD_TICK
thread.setStatus(3); // STATUS_YIELD_TICK
}
yield;
Expand Down Expand Up @@ -113,16 +113,16 @@ const waitPromise = function*(promise) {
// enter STATUS_PROMISE_WAIT and yield
// this will stop script execution until the promise handlers reset the thread status
// because promise handlers might execute immediately, configure thread.status here
thread.status = 1; // STATUS_PROMISE_WAIT
thread.setStatus(1); // STATUS_PROMISE_WAIT
promise
.then(value => {
returnValue = value;
thread.status = 0; // STATUS_RUNNING
thread.setStatus(0); // STATUS_RUNNING
}, error => {
globalState.log.warn('Promise rejected in compiled script:', error);
returnValue = '' + error;
thread.status = 0; // STATUS_RUNNING
thread.setStatus(0); // STATUS_RUNNING
});
yield;
Expand Down Expand Up @@ -177,7 +177,7 @@ const executeInCompatibilityLayer = function*(inputs, blockFunction, isWarp, use
) {
// Yielded threads will run next iteration.
if (thread.status === 2 /* STATUS_YIELD */) {
thread.status = 0; // STATUS_RUNNING
thread.setStatus(0); // STATUS_RUNNING
// Yield back to the event loop when stuck or not in warp mode.
if (!isWarp || isStuck()) {
yield;
Expand Down
4 changes: 2 additions & 2 deletions src/engine/block-utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ class BlockUtility {
* Set the thread to yield.
*/
yield () {
this.thread.status = Thread.STATUS_YIELD;
this.thread.setStatus(Thread.STATUS_YIELD);
}

/**
* Set the thread to yield until the next tick of the runtime.
*/
yieldTick () {
this.thread.status = Thread.STATUS_YIELD_TICK;
this.thread.setStatus(Thread.STATUS_YIELD_TICK);
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/engine/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const handleReport = function (resolvedValue, sequencer, thread, blockCached, la
if (isHat) {
// Hat predicate was evaluated.
if (thread.stackClick) {
thread.status = Thread.STATUS_RUNNING;
thread.setStatus(Thread.STATUS_RUNNING);
} else if (sequencer.runtime.getIsEdgeActivatedHat(opcode)) {
// If this is an edge-activated hat, only proceed if the value is
// true and used to be false, or the stack was activated explicitly
Expand All @@ -74,13 +74,13 @@ const handleReport = function (resolvedValue, sequencer, thread, blockCached, la

const edgeWasActivated = hasOldEdgeValue ? (!oldEdgeValue && resolvedValue) : resolvedValue;
if (edgeWasActivated) {
thread.status = Thread.STATUS_RUNNING;
thread.setStatus(Thread.STATUS_RUNNING);
} else {
sequencer.retireThread(thread);
}
} else if (resolvedValue) {
// Predicate returned true: allow the script to run.
thread.status = Thread.STATUS_RUNNING;
thread.setStatus(Thread.STATUS_RUNNING);
} else {
// Predicate returned false: do not allow script to run
sequencer.retireThread(thread);
Expand Down Expand Up @@ -108,7 +108,7 @@ const handleReport = function (resolvedValue, sequencer, thread, blockCached, la
}
}
// Finished any yields.
thread.status = Thread.STATUS_RUNNING;
thread.setStatus(Thread.STATUS_RUNNING);
}
};

Expand Down Expand Up @@ -144,7 +144,7 @@ const handlePromiseResolution = (resolvedValue, sequencer, thread, blockCached,
const handlePromise = (primitiveReportedValue, sequencer, thread, blockCached, lastOperation) => {
if (thread.status === Thread.STATUS_RUNNING) {
// Primitive returned a promise; automatically yield thread.
thread.status = Thread.STATUS_PROMISE_WAIT;
thread.setStatus(Thread.STATUS_PROMISE_WAIT);
}
// Promise handlers
primitiveReportedValue.then(resolvedValue => {
Expand Down
30 changes: 27 additions & 3 deletions src/engine/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -2253,7 +2253,10 @@ class Runtime extends EventEmitter {
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

// this is a WIP so it should be ignored
/**
* Set the "paused" status of the current project.
* @param {boolean} status The pause status of the project.
*/
setPause(status) {

Check failure on line 2260 in src/engine/runtime.js

View workflow job for this annotation

GitHub Actions / build

Missing space before function parentheses
status = status || false;
const didChange = this.paused !== status;
Expand All @@ -2263,8 +2266,15 @@ class Runtime extends EventEmitter {
this.ioDevices.clock.pause();
}
this.audioEngine.audioContext.suspend();
}
if (!status && didChange) {
for (let i = this.threads.length - 1; i > -1; i--) {
if (this.threads[i].status === 5 /* STATUS_PAUSED */) continue;
this._pauseThread(this.threads[i]);
}
} else if (didChange) {
for (let i = this.threads.length - 1; i > -1; i--) {
if (this.threads[i].status !== 5 /* STATUS_PAUSED */) continue;
this._pauseThread(this.threads[i]);
}
this.audioEngine.audioContext.resume();
this.ioDevices.clock.resume();
}
Expand Down Expand Up @@ -2367,6 +2377,20 @@ class Runtime extends EventEmitter {
return thread;
}

/**
* Pause a thread, this toggles the pause status!
* PLEASE check the status before you use this!
* @param {!Thread} thread Thread object to restart.
*/
_pauseThread(thread) {

Check failure on line 2385 in src/engine/runtime.js

View workflow job for this annotation

GitHub Actions / build

Missing space before function parentheses
if (thread.status === 5 /* STATUS_PAUSED */) {
thread.setStatus(thread.previousStatus);
} else {
thread.setStatus(5); // STATUS_PAUSED
}
}
_

Check failure on line 2392 in src/engine/runtime.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon

emitCompileError (target, error) {
this.emit(Runtime.COMPILE_ERROR, target, error);
}
Expand Down
14 changes: 7 additions & 7 deletions src/engine/sequencer.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Sequencer {
if (activeThread.status === Thread.STATUS_YIELD_TICK &&
!ranFirstTick) {
// Clear single-tick yield from the last call of `stepThreads`.
activeThread.status = Thread.STATUS_RUNNING;
activeThread.setStatus(Thread.STATUS_RUNNING);
}
if (activeThread.status === Thread.STATUS_RUNNING ||
activeThread.status === Thread.STATUS_YIELD) {
Expand Down Expand Up @@ -192,7 +192,7 @@ class Sequencer {

// Did the null follow a hat block?
if (thread.stack.length === 0) {
thread.status = Thread.STATUS_DONE;
thread.setStatus(Thread.STATUS_DONE);
return;
}
}
Expand Down Expand Up @@ -223,7 +223,7 @@ class Sequencer {
// If the thread has yielded or is waiting, yield to other threads.
if (thread.status === Thread.STATUS_YIELD) {
// Mark as running for next iteration.
thread.status = Thread.STATUS_RUNNING;
thread.setStatus(Thread.STATUS_RUNNING);
// In warp mode, yielded blocks are re-executed immediately.
if (isWarpMode &&
thread.warpTimer.timeElapsed() <= Sequencer.WARP_TIME) {
Expand Down Expand Up @@ -252,7 +252,7 @@ class Sequencer {

if (thread.stack.length === 0) {
// No more stack to run!
thread.status = Thread.STATUS_DONE;
thread.setStatus(Thread.STATUS_DONE);
return;
}

Expand Down Expand Up @@ -332,7 +332,7 @@ class Sequencer {
// In known warp-mode threads, only yield when time is up.
if (thread.peekStackFrame().warpMode &&
thread.warpTimer.timeElapsed() > Sequencer.WARP_TIME) {
thread.status = Thread.STATUS_YIELD;
thread.setStatus(Thread.STATUS_YIELD);
} else {
// Look for warp-mode flag on definition, and set the thread
// to warp-mode if needed.
Expand All @@ -352,7 +352,7 @@ class Sequencer {
thread.peekStackFrame().warpMode = true;
} else if (isRecursive) {
// In normal-mode threads, yield any time we have a recursive call.
thread.status = Thread.STATUS_YIELD;
thread.setStatus(Thread.STATUS_YIELD);
}
}
}
Expand All @@ -365,7 +365,7 @@ class Sequencer {
thread.stack = [];
thread.stackFrame = [];
thread.requestScriptGlowInFrame = false;
thread.status = Thread.STATUS_DONE;
thread.setStatus(Thread.STATUS_DONE);
if (thread.isCompiled) {
thread.procedures = null;
thread.generator = null;
Expand Down
21 changes: 19 additions & 2 deletions src/engine/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ class Thread {
*/
this.stackFrames = [];


/**
* The previous status of the thread
* Used by the pause thread feature
* @type {number}
*/
this.previousStatus = 0; /* Thread.STATUS_RUNNING */

/**
* Status of the thread, one of three states (below)
* @type {number}
Expand Down Expand Up @@ -287,6 +295,15 @@ class Thread {
return 5; // used by compiler
}

/**
* Sets the thread status
*/
setStatus(newStatus) {

Check failure on line 301 in src/engine/thread.js

View workflow job for this annotation

GitHub Actions / build

Missing space before function parentheses
this.previousStatus = this.status;
this.status = newStatus;
// todo: Possibly make an event?
}

/**
* @param {Target} target The target running the thread.
* @param {string} topBlock ID of the thread's top block.
Expand Down Expand Up @@ -364,7 +381,7 @@ class Thread {
if (this.stack.length === 0) {
// Clean up!
this.requestScriptGlowInFrame = false;
this.status = Thread.STATUS_DONE;
this.setStatus(Thread.STATUS_DONE);
}
}

Expand Down Expand Up @@ -474,7 +491,7 @@ class Thread {
}

// "run util.yield", and restart the loop block
this.status = Thread.STATUS_YIELD;
this.setStatus(Thread.STATUS_YIELD);
}

// end of borrowed code
Expand Down

0 comments on commit 72f43c9

Please sign in to comment.