@@ -248,7 +248,7 @@ class Runtime extends EventEmitter {
248
248
this . _scriptGlowsPreviousFrame = [ ] ;
249
249
250
250
/**
251
- * Whether any non-monitor threads ran during the previous frame.
251
+ * Whether the project counted as "running" during the previous frame.
252
252
* @type {boolean }
253
253
*/
254
254
this . _projectRanLastFrame = false ;
@@ -1636,13 +1636,16 @@ class Runtime extends EventEmitter {
1636
1636
* @param {?object } opts optional arguments
1637
1637
* @param {?boolean } opts.stackClick true if the script was activated by clicking on the stack
1638
1638
* @param {?boolean } opts.updateMonitor true if the script should update a monitor value
1639
+ * @param {?boolean } opts.edgeActivated true if the script's top block is an edge-activated hat block
1639
1640
* @return {!Thread } The newly created thread.
1640
1641
*/
1641
1642
_pushThread ( id , target , opts ) {
1642
1643
const thread = new Thread ( id ) ;
1643
1644
thread . target = target ;
1645
+ // TODO: make these mutually exclusive (convert to an enum?)
1644
1646
thread . stackClick = Boolean ( opts && opts . stackClick ) ;
1645
1647
thread . updateMonitor = Boolean ( opts && opts . updateMonitor ) ;
1648
+ thread . edgeActivated = Boolean ( opts && opts . edgeActivated ) ;
1646
1649
thread . blockContainer = thread . updateMonitor ?
1647
1650
this . monitorBlocks :
1648
1651
target . blocks ;
@@ -1817,6 +1820,7 @@ class Runtime extends EventEmitter {
1817
1820
const newThreads = [ ] ;
1818
1821
// Look up metadata for the relevant hat.
1819
1822
const hatMeta = instance . _hats [ requestedHatOpcode ] ;
1823
+ const edgeActivated = Boolean ( hatMeta . edgeActivated ) ;
1820
1824
1821
1825
for ( const opts in optMatchFields ) {
1822
1826
if ( ! optMatchFields . hasOwnProperty ( opts ) ) continue ;
@@ -1869,7 +1873,7 @@ class Runtime extends EventEmitter {
1869
1873
}
1870
1874
}
1871
1875
// Start the thread with this top block.
1872
- newThreads . push ( this . _pushThread ( topBlockId , target ) ) ;
1876
+ newThreads . push ( this . _pushThread ( topBlockId , target , { edgeActivated } ) ) ;
1873
1877
} , optTarget ) ;
1874
1878
// For compatibility with Scratch 2, edge triggered hats need to be processed before
1875
1879
// threads are stepped. See ScratchRuntime.as for original implementation
@@ -2094,11 +2098,15 @@ class Runtime extends EventEmitter {
2094
2098
}
2095
2099
this . _updateGlows ( doneThreads ) ;
2096
2100
2097
- const threadNonMonitor = thread => ! thread . updateMonitor ;
2101
+ // Threads count as "running" if a block glowed in the thread this frame.
2102
+ // This excludes edge-activated hat predicates and monitor blocks.
2103
+ const threadCountsTowardsRunStatus = thread => thread . requestScriptGlowInFrame &&
2104
+ thread . blockGlowInFrame !== null ;
2098
2105
// Add done threads so that even if a thread finishes within 1 frame, the green
2099
2106
// flag will still indicate that a script ran.
2100
- const anyNonMonitorThreadsRunning = this . threads . some ( threadNonMonitor ) || doneThreads . some ( threadNonMonitor ) ;
2101
- this . _emitProjectRunStatus ( anyNonMonitorThreadsRunning ) ;
2107
+ const anyThreadsRunning = this . threads . some ( threadCountsTowardsRunStatus ) ||
2108
+ doneThreads . some ( threadCountsTowardsRunStatus ) ;
2109
+ this . _emitProjectRunStatus ( anyThreadsRunning ) ;
2102
2110
// Store threads that completed this iteration for testing and other
2103
2111
// internal purposes.
2104
2112
this . _lastStepDoneThreads = doneThreads ;
0 commit comments