@@ -1049,3 +1049,96 @@ test nested_composite_anonymous = [] {
10491049 expect (sm.is (state<Leaf>));
10501050 expect (sm.is <decltype (state<Leaf>)>(X));
10511051};
1052+
1053+ test composite_state_reentry = [] {
1054+ using namespace boost ::sml;
1055+
1056+ // events
1057+ struct E {};
1058+
1059+ struct Inner {
1060+ // states
1061+ struct START {};
1062+ struct MID {};
1063+ struct END {};
1064+
1065+ auto operator ()() const noexcept {
1066+ using namespace sml ;
1067+
1068+ /* clang-format off */
1069+ return make_transition_table (
1070+ *state<START> = state<MID>,
1071+ state<MID> + event<E> = state<END>,
1072+ state<END> = X
1073+ );
1074+ /* clang-format on */
1075+ }
1076+ };
1077+
1078+ struct Outer {
1079+ // states
1080+ struct START {}; // for demonstrating the workaround
1081+ struct END {};
1082+
1083+
1084+ auto operator ()() const noexcept {
1085+ using namespace sml ;
1086+
1087+ // just runs the inner state machine
1088+ /* clang-format off */
1089+ return make_transition_table (
1090+ *state<Inner> = state<END>,
1091+ state<END> = X
1092+ );
1093+ /* clang-format on */
1094+ }
1095+
1096+ };
1097+
1098+ // events
1099+ struct CONTINUE {};
1100+ struct EXIT {};
1101+
1102+ struct Top {
1103+ // states
1104+ struct MID {};
1105+ struct END {};
1106+
1107+ auto operator ()() const noexcept {
1108+ using namespace sml ;
1109+
1110+ /* clang-format off */
1111+ return make_transition_table (
1112+ *state<Outer> = state<MID>,
1113+ state<MID> + event<CONTINUE> = state<Outer>,
1114+ state<MID> + event<EXIT> = state<END>,
1115+ state<END> = X
1116+ );
1117+ /* clang-format on */
1118+ }
1119+
1120+ };
1121+
1122+ sml::sm<Top> sm;
1123+
1124+ // we should be in the Inner state machine waiting for its event
1125+ expect (sm.is (state<Outer>));
1126+ expect (sm.is <decltype (state<Outer>)>(state<Inner>));
1127+ expect (sm.is <decltype (state<Inner>)>(state<Inner::MID>));
1128+
1129+ // fire the event Inner is waiting for
1130+ expect (sm.process_event (E{}));
1131+
1132+ // now Inner and Outer have both finished and we are sitting in the top level MID
1133+ expect (sm.is (state<Top::MID>));
1134+ expect (sm.is <decltype (state<Outer>)>(X));
1135+ expect (sm.is <decltype (state<Inner>)>(X));
1136+
1137+ // fire CONTINUE to re-enter Outer and therefore Inner
1138+ expect (sm.process_event (CONTINUE{}));
1139+
1140+ // back in Inner waiting for an event
1141+ expect (sm.is (state<Outer>));
1142+ expect (sm.is <decltype (state<Outer>)>(state<Inner>));
1143+ expect (sm.is <decltype (state<Inner>)>(state<Inner::MID>));
1144+ };
0 commit comments