Skip to content

Commit 49ee108

Browse files
GuiCodronkris-jusiak
authored andcommitted
Do not propagate anonymous events to substate
Stop anonymous events from being propagated inside sub state machine. Anonymous events are all triggered by process_event. Without this, each additional layer multiply by 3 the number of times an anonymous event is processed by the sub state machine.
1 parent db6895f commit 49ee108

File tree

4 files changed

+28
-86
lines changed

4 files changed

+28
-86
lines changed

include/boost/sml.hpp

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,11 @@ template <class TSM>
915915
struct transitions_sub<sm<TSM>> {
916916
template <class TEvent, class SM, class TDeps, class TSubs>
917917
static bool execute(const TEvent &event, SM &, TDeps &deps, TSubs &subs, typename SM::state_t &) {
918-
return sub_sm<sm_impl<TSM>>::get(&subs).template process_event<TEvent>(event, deps, subs);
918+
return sub_sm<sm_impl<TSM>>::get(&subs).process_event(event, deps, subs);
919+
}
920+
template <class, class SM, class TDeps, class TSubs>
921+
static bool execute(const anonymous &, SM &, TDeps &, TSubs &, typename SM::state_t &) {
922+
return false;
919923
}
920924
};
921925
} // namespace back
@@ -1336,14 +1340,7 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
13361340
}
13371341
template <class TEvent, class TDeps, class TSubs>
13381342
bool process_event(const TEvent &event, TDeps &deps, TSubs &subs) {
1339-
policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1340-
#if BOOST_SML_DISABLE_EXCEPTIONS
1341-
const auto handled = process_event_impl<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(
1342-
event, deps, subs, states_t{}, aux::make_index_sequence<regions>{});
1343-
#else
1344-
const auto handled =
1345-
process_event_noexcept<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, has_exceptions{});
1346-
#endif
1343+
bool handled = process_internal_events(event, deps, subs);
13471344
do {
13481345
do {
13491346
while (process_internal_events(anonymous{}, deps, subs)) {
@@ -1368,13 +1365,7 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
13681365
}
13691366
template <class TDeps, class TSubs>
13701367
void start(TDeps &deps, TSubs &subs) {
1371-
process_internal_events(on_entry<_, initial>{}, deps, subs);
1372-
do {
1373-
while (process_internal_events(anonymous{}, deps, subs)) {
1374-
}
1375-
process_defer_events(deps, subs, true, aux::type<defer_queue_t<initial>>{}, events_t{});
1376-
} while (process_queued_events(deps, subs, aux::type<process_queue_t<initial>>{}, events_t{}) ||
1377-
process_internal_events(anonymous{}, deps, subs));
1368+
process_event(on_entry<_, initial>{}, deps, subs);
13781369
}
13791370
template <class TEvent, class TDeps, class TSubs, class... Ts,
13801371
__BOOST_SML_REQUIRES(!aux::is_base_of<get_generic_t<TEvent>, events_ids_t>::value &&
@@ -1458,15 +1449,15 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
14581449
aux::index_sequence<Ns...>) {
14591450
const auto lock = thread_safety_.create_lock();
14601451
(void)lock;
1452+
auto handled = false;
14611453
#if defined(__cpp_fold_expressions)
1462-
return ((dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states)), ...);
1454+
((handled |= dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states)), ...);
14631455
#else
1464-
auto handled = false;
14651456
(void)aux::swallow{
14661457
0,
14671458
(handled |= dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states), 0)...};
1468-
return handled;
14691459
#endif
1460+
return handled;
14701461
}
14711462
template <class TMappings, class TEvent, class TDeps, class TSubs, class... TStates>
14721463
bool process_event_impl(const TEvent &event, TDeps &deps, TSubs &subs, const aux::type_list<TStates...> &states,
@@ -1522,13 +1513,7 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
15221513
template <class TDeps, class TSubs, class TEvent>
15231514
bool process_event_no_defer(TDeps &deps, TSubs &subs, const void *data) {
15241515
const auto &event = *static_cast<const TEvent *>(data);
1525-
policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
1526-
#if BOOST_SML_DISABLE_EXCEPTIONS
1527-
const auto handled = process_event_impl<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, states_t{},
1528-
aux::make_index_sequence<regions>{});
1529-
#else
1530-
const auto handled = process_event_noexcept<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, has_exceptions{});
1531-
#endif
1516+
bool handled = process_internal_events(event, deps, subs);
15321517
if (handled && defer_again_) {
15331518
++defer_it_;
15341519
return false;
@@ -2404,14 +2389,6 @@ void update_current_state(SM &, TDeps &deps, TSubs &subs, typename SM::state_t &
24042389
update_composite_states<back::sm_impl<T>>(subs, typename back::sm_impl<T>::has_history_states{},
24052390
typename back::sm_impl<T>::history_states_t{});
24062391
}
2407-
template <class TDeps, class TSubs, class TDstState>
2408-
void process_internal_transitions(TDeps &, TSubs &, const TDstState &) {}
2409-
template <class TDeps, class TSubs, class T>
2410-
void process_internal_transitions(TDeps &deps, TSubs &subs, const state<back::sm<T>> &) {
2411-
auto &sm = back::sub_sm<back::sm_impl<T>>::get(&subs);
2412-
while (sm.process_internal_events(back::anonymous{}, deps, subs)) {
2413-
}
2414-
}
24152392
template <class S1, class S2, class E, class G, class A>
24162393
struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
24172394
static constexpr auto initial = state<S2>::initial;
@@ -2432,7 +2409,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
24322409
state<dst_state>{});
24332410
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
24342411
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
2435-
process_internal_transitions(deps, subs, state<dst_state>{});
24362412
return true;
24372413
}
24382414
return false;
@@ -2444,7 +2420,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
24442420
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
24452421
state<dst_state>{});
24462422
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
2447-
process_internal_transitions(deps, subs, state<dst_state>{});
24482423
return true;
24492424
}
24502425
return false;
@@ -2493,7 +2468,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, A> {
24932468
state<dst_state>{});
24942469
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
24952470
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
2496-
process_internal_transitions(deps, subs, state<dst_state>{});
24972471
return true;
24982472
}
24992473
template <class TEvent, class SM, class TDeps, class TSubs>
@@ -2502,7 +2476,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, A> {
25022476
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
25032477
state<dst_state>{});
25042478
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
2505-
process_internal_transitions(deps, subs, state<dst_state>{});
25062479
return true;
25072480
}
25082481
A a;
@@ -2544,7 +2517,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, none> {
25442517
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
25452518
state<dst_state>{});
25462519
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
2547-
process_internal_transitions(deps, subs, state<dst_state>{});
25482520
return true;
25492521
}
25502522
return false;
@@ -2555,7 +2527,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, none> {
25552527
update_current_state(sm, deps, subs, current_state,
25562528
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
25572529
state<dst_state>{});
2558-
process_internal_transitions(deps, subs, state<dst_state>{});
25592530
return true;
25602531
}
25612532
return false;
@@ -2597,15 +2568,13 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, none> {
25972568
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
25982569
state<dst_state>{});
25992570
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
2600-
process_internal_transitions(deps, subs, state<dst_state>{});
26012571
return true;
26022572
}
26032573
template <class TEvent, class SM, class TDeps, class TSubs>
26042574
bool execute(const TEvent &, SM &sm, TDeps &deps, TSubs &subs, typename SM::state_t &current_state, aux::false_type) {
26052575
update_current_state(sm, deps, subs, current_state,
26062576
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
26072577
state<dst_state>{});
2608-
process_internal_transitions(deps, subs, state<dst_state>{});
26092578
return true;
26102579
}
26112580
__BOOST_SML_ZERO_SIZE_ARRAY(aux::byte);

include/boost/sml/back/state_machine.hpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,8 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
7777

7878
template <class TEvent, class TDeps, class TSubs>
7979
bool process_event(const TEvent &event, TDeps &deps, TSubs &subs) {
80-
policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
80+
bool handled = process_internal_events(event, deps, subs);
8181

82-
#if BOOST_SML_DISABLE_EXCEPTIONS // __pph__
83-
const auto handled = process_event_impl<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(
84-
event, deps, subs, states_t{}, aux::make_index_sequence<regions>{});
85-
#else // __pph__
86-
const auto handled =
87-
process_event_noexcept<get_event_mapping_t<get_generic_t<TEvent>, mappings>>(event, deps, subs, has_exceptions{});
88-
#endif // __pph__
8982
// Repeat internal transition until there is no more to process.
9083
do {
9184
do {
@@ -116,13 +109,7 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
116109

117110
template <class TDeps, class TSubs>
118111
void start(TDeps &deps, TSubs &subs) {
119-
process_internal_events(on_entry<_, initial>{}, deps, subs);
120-
do {
121-
while (process_internal_events(anonymous{}, deps, subs)) {
122-
}
123-
process_defer_events(deps, subs, true, aux::type<defer_queue_t<initial>>{}, events_t{});
124-
} while (process_queued_events(deps, subs, aux::type<process_queue_t<initial>>{}, events_t{}) ||
125-
process_internal_events(anonymous{}, deps, subs));
112+
process_event(on_entry<_, initial>{}, deps, subs);
126113
}
127114

128115
template <class TEvent, class TDeps, class TSubs, class... Ts,
@@ -217,15 +204,15 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
217204
const auto lock = thread_safety_.create_lock();
218205
(void)lock;
219206

207+
auto handled = false;
220208
#if defined(__cpp_fold_expressions) // __pph__
221-
return ((dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states)), ...);
209+
((handled |= dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states)), ...);
222210
#else // __pph__
223-
auto handled = false;
224211
(void)aux::swallow{
225212
0,
226213
(handled |= dispatch_t::template dispatch<0, TMappings>(*this, current_state_[Ns], event, deps, subs, states), 0)...};
227-
return handled;
228214
#endif // __pph__
215+
return handled;
229216
}
230217

231218
template <class TMappings, class TEvent, class TDeps, class TSubs, class... TStates>
@@ -290,13 +277,8 @@ struct sm_impl : aux::conditional_t<aux::is_empty<typename TSM::sm>::value, aux:
290277
template <class TDeps, class TSubs, class TEvent>
291278
bool process_event_no_defer(TDeps &deps, TSubs &subs, const void *data) {
292279
const auto &event = *static_cast<const TEvent *>(data);
293-
policies::log_process_event<sm_t>(aux::type<logger_t>{}, deps, event);
294-
#if BOOST_SML_DISABLE_EXCEPTIONS // __pph__
295-
const auto handled = process_event_impl<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, states_t{},
296-
aux::make_index_sequence<regions>{});
297-
#else // __pph__
298-
const auto handled = process_event_noexcept<get_event_mapping_t<TEvent, mappings>>(event, deps, subs, has_exceptions{});
299-
#endif // __pph__
280+
bool handled = process_internal_events(event, deps, subs);
281+
300282
if (handled && defer_again_) {
301283
++defer_it_;
302284
return false;

include/boost/sml/back/transitions.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct transitions<aux::false_type> {
7272
}
7373
};
7474

75+
/// @brief Event executor on a sub state machine with transition in parent state machine.
7576
template <class TSM, class T, class... Ts>
7677
struct transitions_sub<sm<TSM>, T, Ts...> {
7778
template <class TEvent, class SM, class TDeps, class TSubs>
@@ -103,11 +104,19 @@ struct transitions_sub<sm<TSM>, T, Ts...> {
103104
}
104105
};
105106

107+
/// @brief Event executor on a sub state machine without transition in parent state machine.
106108
template <class TSM>
107109
struct transitions_sub<sm<TSM>> {
108110
template <class TEvent, class SM, class TDeps, class TSubs>
109111
static bool execute(const TEvent& event, SM&, TDeps& deps, TSubs& subs, typename SM::state_t&) {
110-
return sub_sm<sm_impl<TSM>>::get(&subs).template process_event<TEvent>(event, deps, subs);
112+
return sub_sm<sm_impl<TSM>>::get(&subs).process_event(event, deps, subs);
113+
}
114+
115+
template <class, class SM, class TDeps, class TSubs>
116+
static bool execute(const anonymous&, SM&, TDeps&, TSubs&, typename SM::state_t&) {
117+
// Do not propagate anonymous events to sub state machine
118+
// Anonymous events will be generated inside sub-statemachine by initial process_event.
119+
return false;
111120
}
112121
};
113122

include/boost/sml/front/transition.hpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,6 @@ void update_current_state(SM &, TDeps &deps, TSubs &subs, typename SM::state_t &
272272
typename back::sm_impl<T>::history_states_t{});
273273
}
274274

275-
template <class TDeps, class TSubs, class TDstState>
276-
void process_internal_transitions(TDeps &, TSubs &, const TDstState &) {}
277-
278-
template <class TDeps, class TSubs, class T>
279-
void process_internal_transitions(TDeps &deps, TSubs &subs, const state<back::sm<T>> &) {
280-
auto &sm = back::sub_sm<back::sm_impl<T>>::get(&subs);
281-
while (sm.process_internal_events(back::anonymous{}, deps, subs)) {
282-
}
283-
}
284-
285275
template <class S1, class S2, class E, class G, class A>
286276
struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
287277
static constexpr auto initial = state<S2>::initial;
@@ -305,7 +295,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
305295
state<dst_state>{});
306296
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
307297
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
308-
process_internal_transitions(deps, subs, state<dst_state>{});
309298
return true;
310299
}
311300
return false;
@@ -318,7 +307,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, A> {
318307
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
319308
state<dst_state>{});
320309
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
321-
process_internal_transitions(deps, subs, state<dst_state>{});
322310
return true;
323311
}
324312
return false;
@@ -377,7 +365,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, A> {
377365
state<dst_state>{});
378366
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
379367
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
380-
process_internal_transitions(deps, subs, state<dst_state>{});
381368
return true;
382369
}
383370

@@ -387,7 +374,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, A> {
387374
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
388375
state<dst_state>{});
389376
call<TEvent, args_t<A, TEvent>, typename SM::logger_t>::execute(a, event, sm, deps, subs);
390-
process_internal_transitions(deps, subs, state<dst_state>{});
391377
return true;
392378
}
393379

@@ -439,7 +425,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, none> {
439425
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
440426
state<dst_state>{});
441427
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
442-
process_internal_transitions(deps, subs, state<dst_state>{});
443428
return true;
444429
}
445430
return false;
@@ -451,7 +436,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, G, none> {
451436
update_current_state(sm, deps, subs, current_state,
452437
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
453438
state<dst_state>{});
454-
process_internal_transitions(deps, subs, state<dst_state>{});
455439
return true;
456440
}
457441
return false;
@@ -503,7 +487,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, none> {
503487
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
504488
state<dst_state>{});
505489
sm.process_internal_event(back::on_entry<back::_, TEvent>{event}, deps, subs, current_state);
506-
process_internal_transitions(deps, subs, state<dst_state>{});
507490
return true;
508491
}
509492

@@ -512,7 +495,6 @@ struct transition<state<S1>, state<S2>, front::event<E>, always, none> {
512495
update_current_state(sm, deps, subs, current_state,
513496
aux::get_id<typename SM::state_t, dst_state>((typename SM::states_ids_t *)0), state<src_state>{},
514497
state<dst_state>{});
515-
process_internal_transitions(deps, subs, state<dst_state>{});
516498
return true;
517499
}
518500

0 commit comments

Comments
 (0)