Created
June 13, 2021 13:30
-
-
Save leonrinkel/5078b845b60dd6be5fa02a1fe8f6c28a to your computer and use it in GitHub Desktop.
Typescript State Machine
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 TrafficLightOperations { | |
onButtonPressed(): void; | |
onWaitedToTurnGreen(): void; | |
waitToTurnRed(): void; | |
onWaitedToTurnRed(): void; | |
} | |
interface TrafficLightContext { | |
activeLight?: "red" | "green"; | |
} | |
abstract class TrafficLightState implements TrafficLightOperations { | |
protected instance: TrafficLight; | |
constructor(instance: TrafficLight) { | |
this.instance = instance; | |
} | |
public abstract get name(): string; | |
public abstract handle(): void; | |
public onButtonPressed(): TrafficLightState { | |
throw new Error("Method not implemented."); | |
} | |
public onWaitedToTurnGreen(): TrafficLightState { | |
throw new Error("Method not implemented."); | |
} | |
public waitToTurnRed(): TrafficLightState { | |
throw new Error("Method not implemented."); | |
} | |
public onWaitedToTurnRed(): TrafficLightState { | |
throw new Error("Method not implemented."); | |
} | |
} | |
class TrafficLightRedState extends TrafficLightState { | |
public get name(): string { return "Red"; } | |
public handle(): void { | |
this.instance.activeLight = "red"; | |
} | |
public onButtonPressed(): TrafficLightWaitingToTurnGreenState { | |
return new TrafficLightWaitingToTurnGreenState(this.instance); | |
} | |
} | |
class TrafficLightWaitingToTurnGreenState extends TrafficLightState { | |
public get name(): string { return "WaitingToTurnGreen"; } | |
public handle(): void { | |
setTimeout(() => this.instance.onWaitedToTurnGreen(), 1000); | |
} | |
public onWaitedToTurnGreen(): TrafficLightGreenState { | |
return new TrafficLightGreenState(this.instance); | |
} | |
} | |
class TrafficLightGreenState extends TrafficLightState { | |
public get name(): string { return "Green"; } | |
public handle(): void { | |
this.instance.activeLight = "green"; | |
setTimeout(() => this.instance.waitToTurnRed()); | |
} | |
public waitToTurnRed(): TrafficLightWaitingToTurnRedState { | |
return new TrafficLightWaitingToTurnRedState(this.instance); | |
} | |
} | |
class TrafficLightWaitingToTurnRedState extends TrafficLightState { | |
public get name(): string { return "WaitingToTurnRed"; } | |
public handle(): void { | |
setTimeout(() => this.instance.onWaitedToTurnRed(), 1000); | |
} | |
public onWaitedToTurnRed(): TrafficLightRedState { | |
return new TrafficLightRedState(this.instance); | |
} | |
} | |
class TrafficLight implements TrafficLightOperations { | |
private _context: TrafficLightContext; | |
private _state: TrafficLightState; | |
constructor() { | |
this._context = {}; | |
this._state = new TrafficLightRedState(this); | |
} | |
set activeLight(activeLight: "red" | "green" | undefined) { | |
this._context.activeLight = activeLight; | |
console.log(`traffic light changed to ${activeLight}`); | |
} | |
get activeLight() { | |
return this._context.activeLight; | |
} | |
onButtonPressed(): void { | |
this._state = this._state.onButtonPressed(); | |
console.log(`state transitioned to ${this._state.name}`); | |
this._state.handle(); | |
} | |
onWaitedToTurnGreen(): void { | |
this._state = this._state.onWaitedToTurnGreen(); | |
console.log(`state transitioned to ${this._state.name}`); | |
this._state.handle(); | |
} | |
waitToTurnRed(): void { | |
this._state = this._state.waitToTurnRed(); | |
console.log(`state transitioned to ${this._state.name}`); | |
this._state.handle(); | |
} | |
onWaitedToTurnRed(): void { | |
this._state = this._state.onWaitedToTurnRed(); | |
console.log(`state transitioned to ${this._state.name}`); | |
this._state.handle(); | |
} | |
} | |
const trafficLight = new TrafficLight(); | |
setTimeout(() => trafficLight.onButtonPressed(), 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment