diff --git a/src/lib/support/StateMachine.h b/src/lib/support/StateMachine.h index b9b5152512e032..7a9e255b440719 100644 --- a/src/lib/support/StateMachine.h +++ b/src/lib/support/StateMachine.h @@ -48,19 +48,21 @@ struct VariantState : Variant private: template - void Enter() + void Enter(bool & ever) { - if (chip::Variant::template Is()) + if (!ever && chip::Variant::template Is()) { + ever = true; chip::Variant::template Get().Enter(); } } template - void Exit() + void Exit(bool & ever) { - if (chip::Variant::template Is()) + if (!ever && chip::Variant::template Is()) { + ever = true; chip::Variant::template Get().Exit(); } } @@ -68,17 +70,18 @@ struct VariantState : Variant template void GetName(const char ** name) { - if (name && chip::Variant::template Is()) + if (name && !*name && chip::Variant::template Is()) { *name = chip::Variant::template Get().GetName(); } } template - void LogTransition(const char * previous) + void LogTransition(bool & ever, const char * previous) { - if (chip::Variant::template Is()) + if (!ever && chip::Variant::template Is()) { + ever = true; chip::Variant::template Get().LogTransition(previous); } } @@ -94,12 +97,14 @@ struct VariantState : Variant void Enter() { - [](...) {}((this->template Enter(), 0)...); + bool ever = false; + [](...) {}((this->template Enter(ever), 0)...); } void Exit() { - [](...) {}((this->template Exit(), 0)...); + bool ever = false; + [](...) {}((this->template Exit(ever), 0)...); } const char * GetName() @@ -111,7 +116,8 @@ struct VariantState : Variant void LogTransition(const char * previous) { - [](...) {}((this->template LogTransition(previous), 0)...); + bool ever = false; + [](...) {}((this->template LogTransition(ever, previous), 0)...); } }; @@ -215,10 +221,10 @@ class StateMachine : public Context auto newState = mTransitions(mCurrentState, evt); if (newState.HasValue()) { - auto oldState = mCurrentState; - oldState.Exit(); + auto oldState = mCurrentState.GetName(); + mCurrentState.Exit(); mCurrentState = newState.Value(); - mCurrentState.LogTransition(oldState.GetName()); + mCurrentState.LogTransition(oldState); // It is impermissible to dispatch events from Exit() or // LogTransition(), or from the transitions table when a transition // has also been returned. Verify that this hasn't occurred.