cppfsm
cppfsm copied to clipboard
Some weird behavior in execute method
Hi, @eglimi I noticed that we cannot use more transactions than one like that:
FSM::Fsm<States, States::Initial, Triggers> fsm;
fsm.add_transactions({
{ States::Initial, States::A, Triggers::ToA, nullptr, action0 },
{ States::A , States::B, Triggers::ToB, nullptr, action1 },
{ States::B , States::B, Triggers::ToB, nullptr, special },
});
fsm.execute(Triggers::ToA); // ok
fsm.execute(Triggers::ToB); // will be executed only the action1 and special action will be ignored.
But, if we add a guard to the second transaction, then if the guard will return false, the special action will be executed:
FSM::Fsm<States, States::Initial, Triggers> fsm;
fsm.add_transactions({
{ States::Initial, States::A, Triggers::ToA, nullptr, action0 },
{ States::A , States::B, Triggers::ToB, []{ return false; }, action1 },
{ States::B , States::B, Triggers::ToB, nullptr, special },
});
fsm.execute(Triggers::ToA); // ok
fsm.execute(Triggers::ToB); // will be executed special action
So, we can solve this cringe in two different ways:
- Return a list of Fsm_Status;
- Break the for a loop by a guard.
Both of these solutions look like a crutch
I think I have to make a new issue about this situation because my changes do nothing for this bug. 🗿
Originally posted by @GRPilot in https://github.com/eglimi/cppfsm/issues/5#issuecomment-1023980882
Hello @GRPilot
This behaviour is expected. Whenever execute()
is called, there is either 0 or 1 transaction taken, never more. If multiple transactions satisfy the conditions (as in your first example) the order is not specified, and a random one is executed. (Note that this is not true in the current implementation, where the order is given by the container. But client code should not rely on this ordering.)
This is described in the file documentation, section "Semantics". If this were changed, the semantics would change completely.
Given this, I believe the return code is also correct and point 1) is not necessary. For point 2), this is not possible because it is valid to have several transitions from/to the same state(s) with different guards.