diff --git a/interpreter.ts b/interpreter.ts index 2e7a6931..3d023cb8 100644 --- a/interpreter.ts +++ b/interpreter.ts @@ -288,11 +288,12 @@ namespace microcode { return undefined } - public runInstant() { + public runInstant(): boolean { const actuator = this.rule.actuators[0] const param = this.getParamInstant() - this.interp.runAction(this.index, actuator, param) + const ok = this.interp.runAction(this.index, actuator, param) this.kill() + return ok } private runAction() { @@ -493,12 +494,20 @@ namespace microcode { } private switchPage(page: number) { + // need to make sure outstanding events are dropped and no new events + this.eventQueue = [] + this.allowEvents = false + // now stop existing rules this.stopAllRules() // set up new rule closures this.currentPage = page this.program.pages[this.currentPage].rules.forEach((r, index) => { this.ruleClosures.push(new RuleClosure(index, r, this)) }) + // start up timer-based rules (should these be events as well?) + this.ruleClosures.forEach(rc => rc.start(true)) + // restart events + this.allowEvents = true this.addEvent({ kind: MicroCodeEventKind.StartPage, } as StartPageEvent) @@ -507,30 +516,34 @@ namespace microcode { kind: MicroCodeEventKind.StateUpdate, updatedVars: Object.keys(vars2tids), } as StateUpdateEvent) - // start up timer-based rules - this.ruleClosures.forEach(rc => rc.start(true)) } - public runAction(ruleIndex: number, action: Tile, param: any) { + public runAction(ruleIndex: number, action: Tile, param: any): boolean { switch (action) { - case Tid.TID_ACTUATOR_SWITCH_PAGE: + case Tid.TID_ACTUATOR_SWITCH_PAGE: { + // no switch if no param if (param) { - // no switch if no param + // when switching, drop any outstanding events + this.eventQueue = [] this.addEvent({ kind: MicroCodeEventKind.SwitchPage, index: param, } as SwitchPageEvent) + return true } - return + return false + } case Tid.TID_ACTUATOR_CUP_X_ASSIGN: case Tid.TID_ACTUATOR_CUP_Y_ASSIGN: - case Tid.TID_ACTUATOR_CUP_Z_ASSIGN: + case Tid.TID_ACTUATOR_CUP_Z_ASSIGN: { const varName = getParam(action) this.updateState(ruleIndex, varName, param) - return + return true + } default: this.host.execute(action as ActionTid, param) } + return true } private updateState(ruleIndex: number, varName: string, v: number) { @@ -599,8 +612,7 @@ namespace microcode { rc => rc.getOutputResource() == OutputResource.PageCounter ) if (switchPage) { - switchPage.runInstant() - return // others don't get chance to run + if (switchPage.runInstant()) return // others don't get chance to run } const takesTime = live.filter( @@ -616,10 +628,11 @@ namespace microcode { }) } + private allowEvents = false private eventQueueActive = false private eventQueue: MicroCodeEvent[] = [] public addEvent(event: MicroCodeEvent) { - if (!this.running) return + if (!this.running || !this.allowEvents) return this.eventQueue.push(event) }