This:
"Details: The current policy is to stop and re-start the script for all events except key-pressed. Key-pressed events are just ignored if the script for that event is already running."
is not true in special situations.
Consider this Scratch code:
<forever>
<change{ x }by( 1
<end>
<when I receive[ a
<broadcast[ b
<broadcast[ b
<when I receive[ b
<broadcast[ a
FIrst run the <forever>, you will see the number happily go up. Then run the <when I receive[ and you see that the number of processes goes exponentially up.
It has probably to do something with this: if you evaluate
p := ScratchProcess new expression: #().
p stop.
p isRunning
you get true as an answer. From what I got, this is exactly that path that the first b process takes (I may have overlooked something):
proc _ ScratchProcess new expression: blockList.
in: ScratchStageMorph>>startProcessForStatements:, during first broadcast
scratchProc stop.
in: BlockMorph>>stop
in: EventHatMorph>>startForEvent:, during second broadcast, then it is not touched any more, since scratchProc _ nil
processes _ processes select: [:p | p isRunning].
in: ScratchStageMorph>>stepProcesses, after the second broadcast, where the first process is not filtered out.
The real source of a problem may be the
readyToYield _ false.
in ScratchProcess>>runStepFor:.
In the same method the processes that got to run are gracefully sweeped, but this is not true for newly created ones, so the select does not prune them out.
A little note to style-skeptics: this would get caught by the unit tests. If not, now they would show me the situations which would break if I take that readyToYield _ false away. ;-)
Last edited by deerel (2008-08-26 16:22:37)
Offline