Project aims building Finite State Machine
with a human friendly dsl in Kotlin, Java, Groovy.
It is ready to go after adding the JitPack repository and project dependency to your build file!
Gradle :
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.github.hasanguner:state-machine:0.2.1'
}
Maven :
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
...
<dependency>
<groupId>com.github.hasanguner</groupId>
<artifactId>state-machine</artifactId>
<version>0.2.1</version>
</dependency>
It provides building state machines in a human-friendly way with power of the Kotlin DSL. It validates transition definitions when the state machine triggered and then proceeds the defined action if it is presented.
Here is the demonstration of cooking foods in the microwave.
Firstly, we are defining the State
and Event
enum class State {
FOOD_PLACED,
DOOR_CLOSED,
COOKING,
COOKING_INTERRUPTED,
COOKING_FINISHED
}
enum class Event {
CLOSE_DOOR,
SET_TIMER,
OPEN_DOOR,
TIME_IS_UP
}
Then, we are defining the state machine
val stateMachine = StateMachine.withEntry<State, Event>(State.FOOD_PLACED) {
(shouldMove() from State.FOOD_PLACED to State.DOOR_CLOSED).on(Event.CLOSE_DOOR) {
println("Door closed.")
}
(shouldMove() from State.DOOR_CLOSED to State.COOKING).on(Event.SET_TIMER) {
println("Cooking started.")
}
(shouldMove() from State.COOKING to State.COOKING_INTERRUPTED).on(Event.OPEN_DOOR) {
println("Cooking interrupted.")
}
(shouldMove() from State.COOKING_INTERRUPTED to State.COOKING).on(Event.CLOSE_DOOR) {
println("Cooking continues.")
}
(shouldMove() from State.COOKING to State.COOKING_FINISHED).on(Event.TIME_IS_UP) {
println("Cooking finised.")
}
}
Lets run it!
println("-Initial State : [${stateMachine.currentState}]")
println("*Closing door..")
stateMachine.evaluate(Event.CLOSE_DOOR)
println("*Setting timer..")
stateMachine.evaluate(Event.SET_TIMER)
println("-A little naughtiness :)")
repeat(2) {
//naughty developer actions..
println("*Opening door..")
stateMachine.evaluate(Event.OPEN_DOOR)
println("*Closing door..")
stateMachine.evaluate(Event.CLOSE_DOOR)
}
println("-Okay, let's let it cook")
println("*Time is up..")
stateMachine.evaluate(Event.TIME_IS_UP)
println("-Final State : [${stateMachine.currentState}]")
Output:
-Initial State : [FOOD_PLACED]
*Closing door..
Door closed.
*Setting timer..
Cooking started.
-A little naughtiness :)
*Opening door..
Cooking interrupted.
*Closing door..
Cooking continues.
*Opening door..
Cooking interrupted.
*Closing door..
Cooking continues.
-Okay, let's let it cook
*Time is up..
Cooking finised.
-Final State : [COOKING_FINISHED]
You can build the project and run all tests.
./gradlew test