From c99cfdb0e3dee631bc6f08177179255c85f41e68 Mon Sep 17 00:00:00 2001 From: Erik Zenker Date: Mon, 25 Jan 2021 20:22:59 +0100 Subject: [PATCH] fix: Inner external transition overwrites outer internal transition (#140) --- src/include/hsm/details/sm.h | 2 +- src/include/hsm/gen/hsm.h | 25 ++++++++++++------------ test/integration/internal_transition.cpp | 18 ++++++++--------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/include/hsm/details/sm.h b/src/include/hsm/details/sm.h index e14ab46..b10fbdb 100644 --- a/src/include/hsm/details/sm.h +++ b/src/include/hsm/details/sm.h @@ -282,8 +282,8 @@ template class sm { void fill_dispatch_table(OptionalParameters&... optionalParameters) { auto optionalDependency = bh::make_basic_tuple(std::ref(optionalParameters)...); - fill_dispatch_table_with_external_transitions(rootState(), m_statesMap, optionalDependency); fill_dispatch_table_with_internal_transitions(rootState(), m_statesMap, optionalDependency); + fill_dispatch_table_with_external_transitions(rootState(), m_statesMap, optionalDependency); fill_dispatch_table_with_deferred_events(rootState(), optionalDependency); } }; diff --git a/src/include/hsm/gen/hsm.h b/src/include/hsm/gen/hsm.h index 997ef2b..01999d8 100644 --- a/src/include/hsm/gen/hsm.h +++ b/src/include/hsm/gen/hsm.h @@ -1265,11 +1265,11 @@ template constexpr auto collect_child_states(State state) #include #include #include +#include #include #include #include #include -#include namespace hsm { @@ -1344,16 +1344,17 @@ constexpr auto get_internal_transitions = [](auto states) { bh::transform( states, [](auto parentState) { - constexpr auto extend = bh::capture(parentState)([](auto parentState, auto transition) { - // Folowing lines satisfies older gcc -Werror=unused-but-set-parameter - (void) transition; - if constexpr (has_transition_table(parentState)) { - return extend_internal_transition( - transition, collect_child_states(parentState)); - } else { - return bh::make_basic_tuple(); - } - }); + constexpr auto extend + = bh::capture(parentState)([](auto parentState, auto transition) { + // Folowing lines satisfies older gcc -Werror=unused-but-set-parameter + (void)transition; + if constexpr (has_transition_table(parentState)) { + return extend_internal_transition( + transition, collect_child_states(parentState)); + } else { + return bh::make_basic_tuple(); + } + }); return bh::transform(get_internal_transition_table(parentState), extend); }), @@ -2183,8 +2184,8 @@ template class sm { void fill_dispatch_table(OptionalParameters&... optionalParameters) { auto optionalDependency = bh::make_basic_tuple(std::ref(optionalParameters)...); - fill_dispatch_table_with_external_transitions(rootState(), m_statesMap, optionalDependency); fill_dispatch_table_with_internal_transitions(rootState(), m_statesMap, optionalDependency); + fill_dispatch_table_with_external_transitions(rootState(), m_statesMap, optionalDependency); fill_dispatch_table_with_deferred_events(rootState(), optionalDependency); } }; diff --git a/test/integration/internal_transition.cpp b/test/integration/internal_transition.cpp index 4af3f63..5c468db 100644 --- a/test/integration/internal_transition.cpp +++ b/test/integration/internal_transition.cpp @@ -93,8 +93,7 @@ struct MainState { // clang-format off return hsm::transition_table( * hsm::state + hsm::event = hsm::state - , hsm::state + hsm::event = hsm::state - , hsm::state + hsm::event / hsm::log = hsm::state + , hsm::state + hsm::event = hsm::state , hsm::state + hsm::event = hsm::state , hsm::state + hsm::event = hsm::state ); @@ -105,9 +104,9 @@ struct MainState { { // clang-format off return hsm::transition_table( - + (hsm::event / hsm::log), + + (hsm::event ), + (hsm::event / action), - + (hsm::event [fail]), + + (hsm::event [fail] / hsm::log), + (hsm::event [fail] / action) ); // clang-format on @@ -120,19 +119,19 @@ class InternalTransitionTests : public Test { hsm::sm sm; }; -TEST_F(InternalTransitionTests, should_overwrite_external_by_internal_transition) +TEST_F(InternalTransitionTests, should_overwrite_internal_by_inner_external_transition) { ASSERT_TRUE(sm.is(hsm::state)); sm.process_event(e1 {}); - ASSERT_TRUE(sm.is(hsm::state)); + ASSERT_TRUE(sm.is(hsm::state)); } -TEST_F(InternalTransitionTests, should_overwrite_external_by_internal_transition_in_substate) +TEST_F(InternalTransitionTests, should_overwrite_internal_by_inner_transition_in_substate) { sm.process_event(e3 {}); ASSERT_TRUE(sm.is(hsm::state, hsm::state)); sm.process_event(e1 {}); - ASSERT_TRUE(sm.is(hsm::state, hsm::state)); + ASSERT_TRUE(sm.is(hsm::state, hsm::state)); } TEST_F(InternalTransitionTests, should_call_action_on_internal_transition) @@ -170,8 +169,7 @@ TEST_F(InternalTransitionTests, should_guard_internal_transition_with_action) } TEST_F( - InternalTransitionTests, - DISABLED_should_not_overwrite_substate_transition_by_parent_internal_transition) + InternalTransitionTests, should_not_overwrite_substate_transition_by_parent_internal_transition) { sm.process_event(e3 {}); ASSERT_TRUE(sm.is(hsm::state, hsm::state));