amaiorano / hsm

C++ framework library to simplify state-driven code
MIT License
110 stars 39 forks source link

Transition from innerstate to sibling of parent state not executing parent OnExit() #14

Closed Bascy closed 3 years ago

Bascy commented 3 years ago

Is it possible to return a SiblingTransition from an inner state to a sibling of the parent state? I have tried this, and it seems that the OnExit of the parent state is not executed

             Moving    ----   Idling
            /      \
    Opening         Closing

So when returning SiblingTransition<Idling> from state Opening, the OnExit() of Opening is executed, but the OnExit() from Moving is not. Also when enabling TraceLevel::Diagnostic you only see a Pop: Opening and a Sibling: Idling , missing the Pop:Moving

Is this a bug or I i'm doing something wrong? How can I solve this?

amaiorano commented 3 years ago

Hi Bascy,

No, inner states do not control what outer states do by design. This makes the state machine easier to reason about, and to reuse.

One way to solve this problem is to make the Opening state transition to some kind of "done" state, say Moving_Done, and the Moving state would check if (IsInState<Moving_Done>()) return SiblingTransition<Idling>().

I have a section about this technique in the documentation. I highly recommend you read through the doc/wiki, as it explains the way HSM works, and the rationale as well.

Hope this helps!

Bascy commented 3 years ago

Thank you for you quick reply I have been reading the wiki (Excellent work!) ... but not that far yet :)

amaiorano commented 3 years ago

I have been reading the wiki (Excellent work!) ... but not that far yet :)

Thanks! Don't be shy to ask more questions :)