Skip to content

Commit 5877b84

Browse files
jefftrullkris-jusiak
authored andcommitted
Handle anonymous events with process_internal_events
- Address missing initial anonymous transitions in composite states - Eliminate exponential internal generation of anonymous events in nested states
1 parent f232328 commit 5877b84

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

include/boost/sml.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ struct transitions_sub<sm<Tsm>, T, Ts...> {
10131013
if (sub_sm<sm_impl<Tsm>>::cget(&subs).is_terminated()) {
10141014
return transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
10151015
} else {
1016-
return sub_sm<sm_impl<Tsm>>::get(&subs).process_event(event, deps, subs);
1016+
return sub_sm<sm_impl<Tsm>>::get(&subs).process_internal_events(event, deps, subs);
10171017
}
10181018
return false;
10191019
}
@@ -1044,8 +1044,8 @@ struct transitions_sub<sm<Tsm>> {
10441044
return sub_sm<sm_impl<Tsm>>::get(&subs).process_event(event, deps, subs);
10451045
}
10461046
template <class, class SM, class TDeps, class TSubs>
1047-
constexpr static bool execute(const anonymous &, SM &, TDeps &, TSubs &, typename SM::state_t &) {
1048-
return false;
1047+
constexpr static bool execute(const anonymous &, SM &, TDeps &deps, TSubs &subs, typename SM::state_t &) {
1048+
return sub_sm<sm_impl<Tsm>>::get(&subs).process_internal_events(anonymous{}, deps, subs);
10491049
}
10501050
};
10511051
} // namespace back

test/ft/composite.cpp

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -937,14 +937,14 @@ test composite_sub_guards = [] {
937937
bool is_ok = false;
938938
sml::sm<SM> sm{c_, guard_counter, is_ok};
939939
expect(std::vector<calls>{calls::a1_entry} == c_);
940-
expect(guard_counter == 1);
940+
expect(guard_counter <= 2);
941941
guard_counter = {};
942942
sm.process_event(e2{});
943-
expect(guard_counter == 1);
943+
expect(guard_counter <= 2);
944944
guard_counter = {};
945945
is_ok = true;
946946
sm.process_event(e2{});
947-
expect(guard_counter == 1);
947+
expect(guard_counter <= 2);
948948
expect(std::vector<calls>{calls::a1_entry, calls::a1_exit, calls::a2_entry} == c_);
949949
guard_counter = {};
950950
sm.process_event(e1{});
@@ -1002,3 +1002,50 @@ test composite_with_string_names = [] {
10021002
expect(sm.is(X));
10031003
};
10041004
#endif
1005+
1006+
test nested_composite_anonymous = [] {
1007+
using namespace boost::sml;
1008+
1009+
struct Leaf {
1010+
struct INITIAL {};
1011+
struct FINAL {};
1012+
1013+
auto operator()() const {
1014+
using namespace boost::sml;
1015+
1016+
/* clang-format off */
1017+
return make_transition_table(
1018+
*state<INITIAL> = state<FINAL>,
1019+
state<FINAL> = X
1020+
);
1021+
/* clang-format on */
1022+
}
1023+
};
1024+
1025+
struct Top {
1026+
// states
1027+
struct INITIAL {};
1028+
struct SUCCESS {};
1029+
1030+
// events
1031+
struct WIN {};
1032+
struct LOSE {};
1033+
1034+
auto operator()() const {
1035+
using namespace boost::sml;
1036+
1037+
/* clang-format off */
1038+
return make_transition_table(
1039+
*state<INITIAL> = state<Leaf>,
1040+
state<Leaf> + event<LOSE> = X,
1041+
state<Leaf> + event<WIN> = state<SUCCESS>
1042+
);
1043+
/* clang-format on */
1044+
}
1045+
};
1046+
1047+
sm<Top> sm;
1048+
1049+
expect(sm.is(state<Leaf>));
1050+
expect(sm.is<decltype(state<Leaf>)>(X));
1051+
};

0 commit comments

Comments
 (0)