@@ -35,32 +35,6 @@ import { Radio } from "./radio";
3535import { RangeSensor , State } from "./state" ;
3636import { ModuleWrapper } from "./wasm" ;
3737
38- enum StopKind {
39- /**
40- * The main Wasm function returned control to us in a normal way.
41- */
42- Default = "default" ,
43- /**
44- * The program called panic.
45- */
46- Panic = "panic" ,
47- /**
48- * The program requested a reset.
49- */
50- Reset = "reset" ,
51- /**
52- * An internal mode where we do not display the stop state UI as we plan to immediately reset.
53- * Used for user-requested flash or reset.
54- */
55- BriefStop = "brief" ,
56- /**
57- * The user requested the program be interrupted.
58- *
59- * Note the program could finish for other reasons, but should always count as a user stop.
60- */
61- UserStop = "user" ,
62- }
63-
6438export class PanicError extends Error {
6539 constructor ( public code : number ) {
6640 super ( "panic" ) ;
@@ -100,6 +74,8 @@ export class Board {
10074 radio : Radio ;
10175 dataLogging : DataLogging ;
10276
77+ private panicTimeout : any ;
78+
10379 public serialInputBuffer : number [ ] = [ ] ;
10480
10581 private stoppedOverlay : HTMLDivElement ;
@@ -132,19 +108,10 @@ export class Board {
132108 */
133109 private module : ModuleWrapper | undefined ;
134110 /**
135- * Controls the action after the user program completes.
136- *
137- * Determined by a combination of user actions (stop, reset etc) and program actions.
111+ * If undefined, then when main finishes we stay stopped.
112+ * Otherwise we perform the action then clear this field.
138113 */
139- private stopKind : StopKind = StopKind . Default ;
140- /**
141- * Timeout for a pending start call due to StopKind.Reset.
142- */
143- private pendingRestartTimeout : any ;
144- /**
145- * Timeout for the next frame of the panic animation.
146- */
147- private panicTimeout : any ;
114+ private afterStopped : ( ( ) => void ) | undefined ;
148115
149116 constructor (
150117 private notifications : Notifications ,
@@ -389,8 +356,6 @@ export class Board {
389356 if ( this . modulePromise || this . module ) {
390357 throw new Error ( "Module already exists!" ) ;
391358 }
392- clearTimeout ( this . pendingRestartTimeout ) ;
393- this . pendingRestartTimeout = null ;
394359
395360 this . modulePromise = this . createModule ( ) ;
396361 const module = await this . modulePromise ;
@@ -400,17 +365,11 @@ export class Board {
400365 this . displayRunningState ( ) ;
401366 await module . start ( ) ;
402367 } catch ( e : any ) {
403- // Take care not to overwrite another kind of stop just because the program
404- // called restart or panic.
405368 if ( e instanceof PanicError ) {
406- if ( this . stopKind === StopKind . Default ) {
407- this . stopKind = StopKind . Panic ;
408- panicCode = e . code ;
409- }
369+ panicCode = e . code ;
410370 } else if ( e instanceof ResetError ) {
411- if ( this . stopKind === StopKind . Default ) {
412- this . stopKind = StopKind . Reset ;
413- }
371+ const noChangeRestart = ( ) => { } ;
372+ this . afterStopped = noChangeRestart ;
414373 } else {
415374 this . notifications . onInternalError ( e ) ;
416375 }
@@ -427,52 +386,30 @@ export class Board {
427386 this . modulePromise = undefined ;
428387 this . module = undefined ;
429388
430- switch ( this . stopKind ) {
431- case StopKind . Panic : {
432- if ( panicCode === undefined ) {
433- throw new Error ( "Must be set" ) ;
434- }
435- this . displayPanic ( panicCode ) ;
436- break ;
437- }
438- case StopKind . Reset : {
439- this . pendingRestartTimeout = setTimeout ( ( ) => this . start ( ) , 0 ) ;
440- break ;
441- }
442- case StopKind . BriefStop : {
443- // Skip the stopped state.
444- break ;
445- }
446- case StopKind . UserStop : /* Fall through */
447- case StopKind . Default : {
389+ if ( panicCode !== undefined ) {
390+ this . displayPanic ( panicCode ) ;
391+ } else {
392+ if ( this . afterStopped ) {
393+ this . afterStopped ( ) ;
394+ this . afterStopped = undefined ;
395+ setTimeout ( ( ) => this . start ( ) , 0 ) ;
396+ } else {
448397 this . displayStoppedState ( ) ;
449- break ;
450- }
451- default : {
452- throw new Error ( "Unknown stop kind: " + this . stopKind ) ;
453398 }
454399 }
455- this . stopKind = StopKind . Default ;
456400 }
457401
458- async stop ( brief : boolean = false ) : Promise < void > {
402+ async stop (
403+ afterStopped : ( ( ) => void ) | undefined = undefined
404+ ) : Promise < void > {
405+ this . afterStopped = afterStopped ;
459406 if ( this . panicTimeout ) {
460407 clearTimeout ( this . panicTimeout ) ;
461408 this . panicTimeout = null ;
462409 this . display . clear ( ) ;
463- if ( ! brief ) {
464- this . displayStoppedState ( ) ;
465- }
466- }
467- if ( this . pendingRestartTimeout ) {
468- clearTimeout ( this . pendingRestartTimeout ) ;
469- this . pendingRestartTimeout = null ;
470- if ( ! brief ) {
471- this . displayStoppedState ( ) ;
472- }
410+ this . displayStoppedState ( ) ;
473411 }
474412 if ( this . modulePromise ) {
475- this . stopKind = brief ? StopKind . BriefStop : StopKind . UserStop ;
476413 // Avoid this.module as we might still be creating it (async).
477414 const module = await this . modulePromise ;
478415 module . requestStop ( ) ;
@@ -485,10 +422,11 @@ export class Board {
485422
486423 /**
487424 * An external reset.
425+ * reset() in MicroPython code throws ResetError.
488426 */
489427 async reset ( ) : Promise < void > {
490- await this . stop ( true ) ;
491- return this . start ( ) ;
428+ const noChangeRestart = ( ) => { } ;
429+ this . stop ( noChangeRestart ) ;
492430 }
493431
494432 async flash ( filesystem : Record < string , Uint8Array > ) : Promise < void > {
@@ -502,7 +440,7 @@ export class Board {
502440 } ;
503441 if ( this . modulePromise ) {
504442 // If it's running then we need to stop before flash.
505- await this . stop ( true ) ;
443+ return this . stop ( flashFileSystem ) ;
506444 }
507445 flashFileSystem ( ) ;
508446 return this . start ( ) ;
0 commit comments