Skip to content

Commit 9d94b96

Browse files
authored
Merge pull request #101 from microbit-apps/switchPageDebug
careful on switching pages
2 parents e1dd55e + b93b664 commit 9d94b96

1 file changed

Lines changed: 39 additions & 30 deletions

File tree

interpreter.ts

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)