@@ -100,10 +100,9 @@ namespace microcode {
100100 } else if ( resource == OutputResource . Speaker ) music . stopAllSounds ( )
101101 this . actionRunning = false
102102 // give the background fiber chance to finish unless it is waiting
103- while ( ! this . waitingOnTimer ( ) && this . backgroundActive ) {
103+ while ( this . wakeTime == 0 && this . backgroundActive ) {
104104 basic . pause ( 0 )
105105 }
106- this . reset ( )
107106 }
108107
109108 public matchWhen ( tid : number , filter : number = undefined ) : boolean {
@@ -173,13 +172,15 @@ namespace microcode {
173172 if ( this . wakeTime > 0 ) {
174173 basic . pause ( this . wakeTime )
175174 this . wakeTime = 0
176- this . interp . addEvent ( {
177- kind : MicroCodeEventKind . TimerFire ,
178- ruleIndex : this . index ,
179- } as TimerEvent )
180- this . timerGoAhead = false
181- while ( this . ok ( ) && ! this . timerGoAhead ) {
182- basic . pause ( 1 )
175+ if ( this . ok ( ) ) {
176+ this . interp . addEvent ( {
177+ kind : MicroCodeEventKind . TimerFire ,
178+ ruleIndex : this . index ,
179+ } as TimerEvent )
180+ this . timerGoAhead = false
181+ while ( this . ok ( ) && ! this . timerGoAhead ) {
182+ basic . pause ( 1 )
183+ }
183184 }
184185 }
185186
@@ -211,14 +212,13 @@ namespace microcode {
211212 }
212213
213214 private checkForLoopFinish ( ) {
214- if ( ! this . actionRunning ) return
215215 control . waitMicros ( ANTI_FREEZE_DELAY * 1000 )
216216 const actionKind = this . getActionKind ( )
217217 if (
218218 actionKind === ActionKind . Instant ||
219219 getTid ( this . rule . actuators [ 0 ] ) == Tid . TID_ACTUATOR_SHOW_NUMBER
220220 ) {
221- this . reset ( )
221+ this . actionRunning = false
222222 return
223223 }
224224 if ( ! this . atLoop ( ) ) this . modifierIndex ++
@@ -236,7 +236,7 @@ namespace microcode {
236236 ) as number
237237 this . loopIndex ++
238238 if ( this . loopIndex >= loopBound ) {
239- this . reset ( )
239+ this . actionRunning = false
240240 } else {
241241 this . modifierIndex = 0
242242 }
@@ -245,7 +245,7 @@ namespace microcode {
245245 // we move to the next tile in sequence
246246 }
247247 } else {
248- this . reset ( )
248+ this . actionRunning = false
249249 }
250250 }
251251
@@ -288,11 +288,12 @@ namespace microcode {
288288 return undefined
289289 }
290290
291- public runInstant ( ) {
291+ public runInstant ( ) : boolean {
292292 const actuator = this . rule . actuators [ 0 ]
293293 const param = this . getParamInstant ( )
294- this . interp . runAction ( this . index , actuator , param )
294+ const ok = this . interp . runAction ( this . index , actuator , param )
295295 this . kill ( )
296+ return ok
296297 }
297298
298299 private runAction ( ) {
@@ -332,10 +333,6 @@ namespace microcode {
332333 this . interp . processNewState ( )
333334 }
334335
335- private waitingOnTimer ( ) {
336- return this . wakeTime > 0
337- }
338-
339336 private getWakeTime ( ) {
340337 this . wakeTime = 0
341338 const sensor = this . rule . sensor
@@ -495,12 +492,20 @@ namespace microcode {
495492 }
496493
497494 private switchPage ( page : number ) {
495+ // need to make sure outstanding events are dropped and no new events
496+ this . eventQueue = [ ]
497+ this . allowEvents = false
498+ // now stop existing rules
498499 this . stopAllRules ( )
499500 // set up new rule closures
500501 this . currentPage = page
501502 this . program . pages [ this . currentPage ] . rules . forEach ( ( r , index ) => {
502503 this . ruleClosures . push ( new RuleClosure ( index , r , this ) )
503504 } )
505+ // start up timer-based rules (should these be events as well?)
506+ this . ruleClosures . forEach ( rc => rc . start ( true ) )
507+ // restart events
508+ this . allowEvents = true
504509 this . addEvent ( {
505510 kind : MicroCodeEventKind . StartPage ,
506511 } as StartPageEvent )
@@ -509,30 +514,34 @@ namespace microcode {
509514 kind : MicroCodeEventKind . StateUpdate ,
510515 updatedVars : Object . keys ( vars2tids ) ,
511516 } as StateUpdateEvent )
512- // start up timer-based rules
513- this . ruleClosures . forEach ( rc => rc . start ( true ) )
514517 }
515518
516- public runAction ( ruleIndex : number , action : Tile , param : any ) {
519+ public runAction ( ruleIndex : number , action : Tile , param : any ) : boolean {
517520 switch ( action ) {
518- case Tid . TID_ACTUATOR_SWITCH_PAGE :
521+ case Tid . TID_ACTUATOR_SWITCH_PAGE : {
522+ // no switch if no param
519523 if ( param ) {
520- // no switch if no param
524+ // when switching, drop any outstanding events
525+ this . eventQueue = [ ]
521526 this . addEvent ( {
522527 kind : MicroCodeEventKind . SwitchPage ,
523528 index : param ,
524529 } as SwitchPageEvent )
530+ return true
525531 }
526- return
532+ return false
533+ }
527534 case Tid . TID_ACTUATOR_CUP_X_ASSIGN :
528535 case Tid . TID_ACTUATOR_CUP_Y_ASSIGN :
529- case Tid . TID_ACTUATOR_CUP_Z_ASSIGN :
536+ case Tid . TID_ACTUATOR_CUP_Z_ASSIGN : {
530537 const varName = getParam ( action )
531538 this . updateState ( ruleIndex , varName , param )
532- return
539+ return true
540+ }
533541 default :
534542 this . host . execute ( action as ActionTid , param )
535543 }
544+ return true
536545 }
537546
538547 private updateState ( ruleIndex : number , varName : string , v : number ) {
@@ -601,8 +610,7 @@ namespace microcode {
601610 rc => rc . getOutputResource ( ) == OutputResource . PageCounter
602611 )
603612 if ( switchPage ) {
604- switchPage . runInstant ( )
605- return // others don't get chance to run
613+ if ( switchPage . runInstant ( ) ) return // others don't get chance to run
606614 }
607615
608616 const takesTime = live . filter (
@@ -618,10 +626,11 @@ namespace microcode {
618626 } )
619627 }
620628
629+ private allowEvents = false
621630 private eventQueueActive = false
622631 private eventQueue : MicroCodeEvent [ ] = [ ]
623632 public addEvent ( event : MicroCodeEvent ) {
624- if ( ! this . running ) return
633+ if ( ! this . running || ! this . allowEvents ) return
625634 this . eventQueue . push ( event )
626635 }
627636
0 commit comments