Skip to content

Instantly share code, notes, and snippets.

@Steven24K
Created June 30, 2021 12:07
Show Gist options
  • Save Steven24K/bc756773830b192e7e13a56de28ad1df to your computer and use it in GitHub Desktop.
Save Steven24K/bc756773830b192e7e13a56de28ad1df to your computer and use it in GitHub Desktop.
A small statemachine in Typescript
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