diff --git a/lib/include/srslte/common/fsm.h b/lib/include/srslte/common/fsm.h index 02cf7e1f3..13d54264c 100644 --- a/lib/include/srslte/common/fsm.h +++ b/lib/include/srslte/common/fsm.h @@ -54,9 +54,6 @@ struct to_states { size_t state_idx; }; -//! Return for when there is no state transition -struct same_state {}; - //! Forward declaration template class fsm_t; @@ -83,15 +80,6 @@ struct to_state_visitor { PrevState* p; }; -//! Visitor to call current state enter method for a given FSM -template -struct enter_visitor { - explicit enter_visitor(FSM* f_) : f(f_) {} - template - void operator()(State&& s); - FSM* f; -}; - //! Helper metafunctions template using enable_if_fsm_state = typename std::enable_if()>::type; @@ -132,8 +120,7 @@ struct fsm_helper { // call FSM enter function f->enter(*s); // call initial substate enter - fsm_details::enter_visitor visitor{s->derived()}; - srslte::visit(visitor, s->derived()->states); + call_enter(s->derived(), &s->derived()->states.template get_unchecked()); } template static disable_if_subfsm call_enter(FSM* f, State* s) @@ -141,17 +128,6 @@ struct fsm_helper { f->enter(*s); } - //! Stayed in same state - template - static void handle_state_change(FSM* f, same_state* s, PrevState* p) - { - // do nothing - } - template - static void handle_state_change(FSM* f, to_state* s, PrevState* p) - { - // do nothing - } //! TargetState is type-erased (a choice). Apply its stored type to the fsm current state template static void handle_state_change(FSM* f, to_states* s, PrevState* p) @@ -163,7 +139,12 @@ struct fsm_helper { template static auto handle_state_change(FSM* f, to_state* s, PrevState* p) -> enable_if_fsm_state { - static_assert(not std::is_same::value, "State cannot transition to itself.\n"); + if (std::is_same::value) { + f->log_h->info("FSM \"%s\": No transition occurred while in state \"%s\"\n", + get_type_name().c_str(), + get_type_name().c_str()); + return; + } f->exit(f->states.template get_unchecked()); f->states.template transit(); f->log_h->info("FSM \"%s\": Detected transition \"%s\" -> \"%s\"", @@ -239,13 +220,6 @@ void to_state_visitor::operator()() fsm_helper::handle_state_change(f, &t, p); } -template -template -void enter_visitor::operator()(State&& s) -{ - fsm_helper::call_enter(f, &s); -} - } // namespace fsm_details //! Gets the typename currently stored in the choice_t @@ -295,6 +269,7 @@ public: struct state_list : public std::tuple { using tuple_base_t = std::tuple; using init_state_t = typename std::decay(std::declval()))>::type; + static_assert(not type_list_contains(), "An FSM cannot contain itself as state\n"); template state_list(fsm_t* f, Args&&... args) : tuple_base_t(std::forward(args)...) @@ -490,7 +465,7 @@ protected: using fsm_t::exit; template - auto react(State&, srslte::proc_launch_ev e) -> srslte::same_state + auto react(State&, srslte::proc_launch_ev e) -> to_state { log_h->warning("Unhandled event \"launch\" caught when procedure is already running\n"); return {}; diff --git a/lib/test/common/fsm_test.cc b/lib/test/common/fsm_test.cc index e7072e52b..f0a3e840f 100644 --- a/lib/test/common/fsm_test.cc +++ b/lib/test/common/fsm_test.cc @@ -61,7 +61,7 @@ public: void exit(state_inner2& s) { log_h->info("fsm1::%s::exit called\n", srslte::get_type_name(s).c_str()); } // FSM2 transitions - auto react(state_inner& s, ev1 e) -> srslte::same_state; + auto react(state_inner& s, ev1 e) -> to_state; auto react(state_inner& s, ev2 e) -> to_state; auto react(state_inner2& s, ev2 e) -> to_state; @@ -107,7 +107,7 @@ void fsm1::enter(state1& s) } // FSM event handlers -auto fsm1::fsm2::react(state_inner& s, ev1) -> srslte::same_state +auto fsm1::fsm2::react(state_inner& s, ev1) -> to_state { log_h->info("fsm2::state_inner::react called\n"); return {}; @@ -125,13 +125,13 @@ auto fsm1::fsm2::react(state_inner2& s, ev2) -> to_state return {}; } -auto fsm1::react(idle_st& s, ev1 e) -> srslte::to_state +auto fsm1::react(idle_st& s, ev1 e) -> to_state { log_h->info("%s::react called\n", srslte::get_type_name(s).c_str()); foo(e); return {}; } -auto fsm1::react(state1& s, ev1) -> srslte::to_state +auto fsm1::react(state1& s, ev1) -> to_state { log_h->info("%s::react called\n", srslte::get_type_name(s).c_str()); return {}; @@ -246,7 +246,7 @@ protected: // example of uncaught event handling template - srslte::same_state react(State& s, int e) + to_state react(State& s, int e) { log_h->info("I dont know how to handle an \"int\" event\n"); return {}; @@ -342,7 +342,6 @@ protected: // on power-off go to deregistered state. Disable react if we are already in deregistered template auto react(AnyState& s, power_off_ev ev) -> to_state; - auto react(emm_deregistered& s, power_off_ev ev) -> srslte::same_state { return {}; } state_list