amaiorano / hsm

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

Why is the state stack processed from outermost to innermost? #21

Closed LouisChen1905 closed 2 years ago

LouisChen1905 commented 2 years ago

Consider this case:

  1. outer state A handles an event E
  2. A has several inner states: B, C, D
  3. B and C ignore event E
  4. D handles E differently from A.

According to https://github.com/amaiorano/hsm/wiki/Chapter-3.-The-H-in-HSM#algorithm and based on my understanding, state stack is processed from the outermost state, e.g. state A. If A::GetTransition() returns SiblingTransition() or InnerTransition() and the current state is D, then D is popped from stack and has no chance to handle the event.

Pls correct me if I was wrong.

amaiorano commented 2 years ago

Hi @LouisChen1905,

Your understanding is correct. The reason it works this way is because in general, each layer of the hierarchical state machine can be thought of as its own flat state machine; so the conditions for a transition at each layer are usually different. For example, outer states Outer1 and Outer2 will transition between each other based on some condition, but Inner1 and Inner2 within Outer1 will not use the same condition to transition between each other.

If you do find yourself in a situation where both an outer state and an inner state have the same transition condition, then it may be because the design isn't quite right. However, if you're convinced that it is, then you can work around this by adding an additional !IsInState<Inner> check, for example in the Outer state. Or perhaps use a StateValue bool that says whether this transition can be handled or not by the outer state.

Finally, it's worth mentioning that if you want to do "event handling" from innermost to outermost state on the current state stack, you can always do so by adding a virtual function to your base state, and manually iterating over the state stack using Begin/EndInnerToOuter() to invoke that function on each state.

Hope this helps.

LouisChen1905 commented 2 years ago

Hi, @amaiorano

Finally, it's worth mentioning that if you want to do "event handling" from innermost to outermost state on the current state stack, you can always do so by adding a virtual function to your base state, and manually iterating over the state stack using Begin/EndInnerToOuter() to invoke that function on each state.

Thanks for replying. I'll try your method.

amaiorano commented 2 years ago

Thanks