Search code examples
javatriggersstatefsm

how to send parameter in stateless4j trigger


I'm using stateless4j as a Finite State Machine library for my app, but I can't understand how to use parameters when firing triggers. I have the following code:

gameFSM.Configure(GameState.LOOKING_FOR_A_QUEST)
    .OnEntry(Actions.lookForQuest)
    .Permit(GameTrigger.QUEST_FOUND, GameState.JUDGING_QUEST);

gameFSM.Configure(GameState.JUDGING_QUEST)
    .OnEntry(Actions.judgeQuest)
    .Permit(GameTrigger.QUEST_ACCEPTED, GameState.INACTIVE) /* test */
    .Permit(GameTrigger.QUEST_DENIED, GameState.LOOKING_FOR_A_QUEST);

gameFSM.Configure(GameState.INACTIVE)
    .Permit(GameTrigger.START_LOOKING_FOR_QUESTS, GameState.LOOKING_FOR_A_QUEST);

Now I'm trying to create a parameter for the transition from LOOKING_FOR_A_QUEST to QUEST_ACCEPTED. I tried the following:

TriggerWithParameters1<Quest, GameState, GameTrigger> twp = gameFSM.SetTriggerParameters(GameTrigger.QUEST_FOUND, Quest);

But I not only don't understand how to Fire this trigger later, I also don't have a clue about what I'm creating with that snip. Can someone tell me how do I proceed with creating and firing that trigger with a parameter, like gameFSM.trigger(GameTrigger.QUEST_FOUND, new Quest());? Thanks!

Bonus: Why every single method in the StateMachine class can throw a suspicious and clueless Exception? I feel this library is so fluent, yet so terrible to use. Any recommendations?


Solution

  • Looks like you ran into the same frustration that I did. I was able to pass the parameters by doing the following:

    TriggerWithParameters1 twp = sm.setTriggerParameters(Trigger.D, java.util.Map.class);
    sm.configure(State.D).permit(Trigger.A, State.A)
                         .onEntryFrom( twp, new Action1<Map>(){ 
                                                public void doIt(Map m) {
                                                   System.out.println(m.toString());
                                                }
                                            }, Map.class);
    Map data = new HashMap();
    data.put("a", "1");
    sm.fire(twp, data);
    

    This approach seems overly complicated, but it does work.