Closed wwadge closed 11 years ago
Hi,
thanks. There is actually a DotExporter already (https://github.com/thehiflyer/Fettle/blob/master/src/main/java/se/fearless/fettle/export/DotExporter.java) that manages to do this. You are of course free to write your own version or give me suggestions on how to improve the existing one. Are there any methods you are missing?
Awesome - sorry I missed that!
I started off by looking at stateless4j but the code's a mess while yours is nice and clean. The only thing I can't see an equivalent of is hierarchical states eg in a credit card transaction you could have AUTH with substates being set as AUTH_PENDING, AUTH_RECEIVED etc. Yes they're separate internally but via the API you could ask: "is it is an AUTH state or one of it's substates?" i.e. it's a purely logical api call.
Congrats once again on your codebase and thanks for making this public.
I've thought about it quite a bit but I haven't really been able to see how it could fit in the Fettle model. I guess the best way to do it is to add that kind of semantics to the states themselves. Something like this:
package se.fearless.fettle;
import com.google.common.collect.Lists;
import org.junit.Test;
import se.fearless.fettle.builder.StateMachineBuilder;
import java.util.List;
import static org.junit.Assert.assertTrue;
public class Foo {
@Test
public void subStates() {
StateMachineBuilder<State, String, Void> builder = StateMachineBuilder.create(State.class, String.class);
builder.transition().from(State.A).to(State.B1).on("ab");
builder.transition().from(State.B1).to(State.B2).on("b1b2");
builder.transition().from(State.B2).to(State.B3).on("b2b3");
builder.transition().from(State.B3).to(State.C).on("bc");
StateMachine<State, String, Void> stateMachine = builder.build(State.A);
stateMachine.fireEvent("ab");
stateMachine.fireEvent("b1b2");
State currentState = stateMachine.getCurrentState();
assertTrue(currentState.isIn(State.B));
assertTrue(currentState.isIn(State.B2));
}
private enum State {
A,
B,
B1(B), B2(B), B3(B),
C;
private final List<State> superStates;
State(State... superStates) {
this.superStates = Lists.newArrayList(superStates);
}
public boolean isIn(State state) {
return this == state || superStates.contains(state);
}
}
}
I will close this issue. If you don't think that my solution is good enough and have an idea on how to integrate it into the framework, please open another issue since it's not really related to the original issue.
Agreed re closing. I'd just change isIn() method to be recursive upwards rather than just .contains() like you'd do in .equals
Nice work.
It would be nice if there's a way to expose the state machine links so that you could for e.g. dump out the state for processing by "dot" to produce a graphic image.