Define a state machine in /source/main/smc/
Turnstile
.sm (more details in
http://smc.sourceforge.net/slides/SMC_Tutorial.pdf) and compile with "mvn smc:smc"
// use a Turnstile java
interface instead of a class; much more flexible!
%class Turnstile
// Package in which the generated state machine source lies
%package turnstile
// Import stuff you need
%import org.vertx.java.core.json.JsonObject
// Initial State of the state machine
%start MainMap::Locked
// MainMap
Transition Table; SMC supports multiple TT
%map MainMap
%%
// State Transition [guard] End State Action(s)
Locked
{
coin(amount: double) [ctxt.isSufficient(amount)]
Unlocked { unlock(); }
coin(amount: double) [!ctxt.isSufficient(amount)]
nil { unlock(); }
pass nil { alarm(); }
}
Unlocked
{
pass Locked { lock(); }
coin(amount: double)
nil { thankyou(); }
}
%%
The
state machine compiler generate TurnstileContext.java in turnstile
package (/target/generated-sources/smc/smc/). Create an "Turnstile"
interface in your main source dir (/source/main/java) in the turnstile
package. Add the missing methods to the interface:
unlock
,
alarm,
lock
,
thankyou
.
The following code shows the implementation of TurnstileComponent.java
with the TurnstileContext state machine and SimpleTurnstile
(state-dependent behavior) implementation:
package turnstile;
import net.kuujo.vertigo.java.ComponentVerticle;
import org.vertx.java.core.Handler;
public class TurnstileComponent extends ComponentVerticle {
private Turnstile businessObject = new SimpleTurnstile();
private TurnstileContext fsm = new TurnstileContext(businessObject);
@Override
public void start() {
super.start();
input.port("coin").messageHandler(new Handler<Double>() {
@Override
public void handle(Double money) {
fsm.coin(money);
}
});
input.port("pass").messageHandler(new Handler<Object>() {
@Override
public void handle(Object event) {
fsm.pass();
}
});
}
class SimpleTurnstile implements Turnstile {
@Override
public void unlock() {
System.out.println("UNLOCK");
}
@Override
public void alarm() {
System.out.println("ALARM");
}
@Override
public void thankyou() {
System.out.println("THANKS");
}
@Override
public void lock() {
System.out.println("LOCK");
}
@Override
public boolean isSufficient(double money) {
return money > 2;
}
}
}
Any suggestions / feedback? Should I share the turnstile tutorial project on github?