Created
June 30, 2021 12:07
-
-
Save Steven24K/bc756773830b192e7e13a56de28ad1df to your computer and use it in GitHub Desktop.
A small statemachine in Typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface StateMachine { | |
busy: boolean | |
update: () => void | |
reset: () => void | |
} | |
interface Seq extends StateMachine { | |
sm1: StateMachine | |
sm2: StateMachine | |
current: StateMachine, | |
next: StateMachine | |
} | |
const Seq = (sm1: StateMachine, sm2: StateMachine): Seq => ({ | |
sm1: sm1, | |
sm2: sm2, | |
current: sm1, | |
next: sm2, | |
busy: true, | |
update: function() { | |
if (this.busy) { | |
this.current.update() | |
if (!this.current.busy) { | |
this.current = this.next | |
} | |
if (!this.next.busy) { | |
this.busy = false | |
} | |
} | |
}, | |
reset: function () { | |
this.sm1.reset() | |
this.sm2.reset() | |
this.current = this.sm1 | |
this.busy = true | |
}, | |
}) | |
interface Print extends StateMachine { | |
message: string | |
} | |
const Print = (msg: string): Print => ({ | |
message: msg, | |
busy: true, | |
update: function() { | |
console.log(this.message) | |
this.busy = false | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
interface Done extends StateMachine { | |
} | |
const Done = (msg: string): Done => ({ | |
busy: true, | |
update: function() { | |
this.busy = false | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
interface Timer extends StateMachine { | |
time: number | |
} | |
const Timer = (time: number): Timer => ({ | |
time: time, | |
busy: true, | |
update: function() { | |
setTimeout(() => { | |
this.busy = false | |
}, time) | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
interface Wait extends StateMachine { | |
predicate: () => boolean | |
} | |
const Wait = (p: () => boolean): Wait => ({ | |
predicate: p, | |
busy: true, | |
update: function() { | |
if (this.predicate()) { | |
this.busy = false | |
} | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
interface Repeat extends StateMachine { | |
action: StateMachine | |
} | |
const Repeat = (action: StateMachine): Repeat => ({ | |
action: action, | |
busy: true, | |
update: function() { | |
if (!this.action.busy) { | |
this.reset() | |
} | |
this.action.update() | |
}, | |
reset: function() { | |
action.reset() | |
} | |
}) | |
interface Call extends StateMachine { | |
action: () => void | |
} | |
const Call = (action: () => void): Call => ({ | |
action: action, | |
busy: true, | |
update: function() { | |
this.action() | |
this.busy = false | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
interface CallIf extends StateMachine { | |
guard: () => boolean | |
action: () => void | |
} | |
const CallIf = (guard: () => boolean, action: () => void): CallIf => ({ | |
guard: guard, | |
action: action, | |
busy: true, | |
update: function() { | |
if (this.guard()) { | |
this.action() | |
} | |
this.busy = false | |
}, | |
reset: function() { | |
this.busy = true | |
} | |
}) | |
let program = Repeat(Seq(Print("Hello"), Seq(Timer(3000), Seq(Print("World"), Call(() => console.clear()))))) | |
let interval = setInterval(() => { | |
program.update() | |
if (!program.busy) { | |
clearInterval(interval) | |
} | |
}, 2000) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment