squirrel
squirrel copied to clipboard
ExternalTransition calls the same method twice
This is my first FSM in Java, and Squirrel has been an amazing tool for that. But I'm having a problem.
public class OrangutanWriter {
public static void main(String[] args) {
StateMachineBuilder<OrangutanWriterFSM, FSMState, FSMEvent, Void> builder = StateMachineBuilderFactory
.create(OrangutanWriterFSM.class, FSMState.class,
FSMEvent.class, Void.class);
builder.onExit(FSMState.StandBy).callMethod("exitStandBy");
builder.externalTransition().from(FSMState.StandBy).to(FSMState.Stream)
.on(FSMEvent.Connected).callMethod("entryStream");
These are some of the transitions defined, but when "FSMEvent.Connected" happens, the FSM enters two times to the method "entryStream".
I have this sysout at the beginning of the method.
System.out .println("\n--------------------------------------Entering to Streamming--------------------------------------" + "\nFrom:" + from + " - To: " + to + " - Event triggered: " + event);
and I get this at the console.
--------------------------------------Entering to Streamming-------------------------------------- From:StandBy - To: Stream - Event triggered: Connected Stream Service has Started @ 3600
--------------------------------------Entering to Streamming-------------------------------------- From:null - To: Stream - Event triggered: Connected Stream Service has Started @ 3600
Is this normal, am I defining something wrong?
Thanks for the assistance.
Spartan
Thanks for reporting this issue. Normally transition should only be triggered once when single event fired. I don't know what is the problem now. It would be helpful if you could provide complete runnable test case to reproduce the issue.
It's weird because I'm just checking the FSM with keyboard events.
public class OrangutanWriter {
private static OrangutanWriterFSM StateMachine;
public static void setup() {
StateMachineBuilder<OrangutanWriterFSM, FSMState, FSMEvent, Void> builder = StateMachineBuilderFactory
.create(OrangutanWriterFSM.class, FSMState.class,
FSMEvent.class, Void.class);
builder.onExit(FSMState.StandBy).callMethod("exitStandBy");
builder.externalTransition().from(FSMState.StandBy).to(FSMState.Stream)
.on(FSMEvent.Connected).callMethod("entryStream");
builder.onExit(FSMState.Stream).callMethod("exitStream");
builder.externalTransition().from(FSMState.Stream).to(FSMState.Encode)
.on(FSMEvent.EncodeList).callMethod("Encode");
// 4. Use State Machine
StateMachine = builder.newStateMachine(FSMState.StandBy);
}
public static void main(String[] args) {
setup();
StateMachine.start();
while (true) {
int myint = 0;
Scanner keyboard = new Scanner(System.in);
System.out.println("You are at: " + StateMachine.getCurrentState()
+ "\nEnter an integer:");
myint = keyboard.nextInt();
switch (myint) {
case 1:
System.out.println("My Int = " + myint);
StateMachine.fire(FSMEvent.Connected);
myint = 0;
break;
case 4:
StateMachine.fire(FSMEvent.EncodeList);
break;
case 5:
StateMachine.fire(FSMEvent.StopEncode);
break;
default:
break;
}
}
}
}
FSM will call method "exitStandBy" when you initial FSM.
like this.
StateMachine = builder.newStateMachine(FSMState.StandBy);
Because of this code.
builder.onExit(FSMState.StandBy).callMethod("exitStandBy");
You can avoid initial call by check FSMEvent is not null.
protected void exitStandBy(FSMState from, FSMState to, FSMEvent event, Void context) { if (event != null) { //your code } }