Given this:
public enum States implements StateEnum {
SHOWING_WELCOME,
WAITING_FOR_PIN,
CHECKING_PIN,
RETURNING_CARD,
SHOWING_MAIN_MENU,
SHOWING_PIN_INVALID,
SHOWING_CARD_LOCKED,
SHOWING_BALANCE,
SHOWING_WITHDRAW_MENU,
SHOWING_TAKE_CASH,
TERMINATED
}
public enum Events implements EventEnum {
cardPresent,
cardExtracted,
pinProvided,
pinValid,
pinInvalid,
tryAgain,
noMoreTries,
cancel,
confirm,
menuShowBalance,
menuWithdrawCash,
menuExit,
switchOff,
cashExtracted
}
I would like to know if there is a way to create an algorithm to automatize this:
from(SHOWING_WELCOME).transit(
on(cardPresent).to(WAITING_FOR_PIN).transit(
on(pinProvided).to(CHECKING_PIN).transit(
on(pinValid).to(SHOWING_MAIN_MENU).transit(
on(menuShowBalance).to(SHOWING_BALANCE).transit(
on(cancel).to(SHOWING_MAIN_MENU)
),
on(menuWithdrawCash).to(SHOWING_WITHDRAW_MENU).transit(
on(cancel).to(SHOWING_MAIN_MENU),
on(confirm).to(SHOWING_TAKE_CASH).transit(
on(cashExtracted).to(SHOWING_MAIN_MENU)
)
),
on(menuExit).to(RETURNING_CARD)
),
on(pinInvalid).to(SHOWING_PIN_INVALID).transit(
on(tryAgain).to(WAITING_FOR_PIN),
on(noMoreTries).to(SHOWING_CARD_LOCKED).transit(
on(confirm).to(SHOWING_WELCOME)
),
on(cancel).to(RETURNING_CARD)
)
),
on(cancel).to(RETURNING_CARD).transit(
on(cardExtracted).to(SHOWING_WELCOME)
)
),
on(switchOff).finish(TERMINATED)
);
I was thinking to create two list (Events and States) to use the values in this way:
on(Events.valueOf(EventsList.get(0))).to(States.valueOf(EventsList.get(0)).trans it(
...
But, Im not sure which is the pattern for iterating.
I really appreciate any advise.
Thank you
//////////////////////////// UPDATED///////////////////////////////////
Solution based on the @Dukeling advice
public Map<States, List<Events>> transitMap;
public Map<Events, States> toMap;
void transitCaller(States initialState, Events events)
{
transitCallerHelper(on(events).to(initialState),
transitMap.get(initialState));
}
Transition transitCallerHelper(Transition toResult, List<Events> events)
{
List<Transition> transitCalls = new ArrayList<Transition>();
for (Events e: events)
{
States s = toMap.get(e);
if (isFinishEvent(e)) // or isFinishState(s)
transitCalls.add(on(e).finish(s));
else
{
events = (s != null ? transitMap.get(s) : null);
if (events == null)
transitCalls.add(on(e).to(s));
else
transitCalls.add(transitCallerHelper(on(e).to(s), events));
}
}
return toResult.transit(transitCalls.get(0));
}