From 8d3427e88a391682421fd37c668c9e8e78ce4602 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 3 Apr 2020 17:47:46 +0100 Subject: [PATCH] removed namespacing from state printing --- lib/include/srslte/common/fsm.h | 79 ++++++++++++++++++++++----------- lib/test/common/fsm_test.cc | 36 +++++++-------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/lib/include/srslte/common/fsm.h b/lib/include/srslte/common/fsm.h index 1263f6af9..cd62a2c54 100644 --- a/lib/include/srslte/common/fsm.h +++ b/lib/include/srslte/common/fsm.h @@ -31,14 +31,22 @@ #include #include +namespace srslte { + //! Helper to print the name of a type for logging #if defined(__GNUC__) && !defined(__clang__) template std::string get_type_name() { - static const char* s = __PRETTY_FUNCTION__; - static const char* pos1 = strchr(s, '=') + 2; - return std::string{pos1, strchr(pos1, ';')}; + static const char* funcname = __PRETTY_FUNCTION__; + static const std::string s = []() { + static const char* pos1 = strchr(funcname, '=') + 2; + static const char* pos2 = strchr(pos1, ';'); + std::string s2{pos1, pos2}; + size_t colon_pos = s2.rfind(':'); + return colon_pos == std::string::npos ? s2 : s2.substr(colon_pos + 1, s2.size()); + }(); + return s; } #else template @@ -55,8 +63,6 @@ std::string get_type_name(const T& t) return get_type_name(); } -namespace srslte { - //! When there is no state transition struct same_state { }; @@ -102,22 +108,6 @@ struct fsm_helper { } static void call_exit(...) {} - template - struct variant_convert { - variant_convert(FSM* f_, PrevState* p_) : f(f_), p(p_) {} - template - void operator()(State& s) - { - static_assert(not std::is_same::type, typename std::decay::type>::value, - "State cannot transition to itself.\n"); - call_exit(f, &srslte::get(f->states)); - f->states.transit(std::move(s)); - call_enter(f, &srslte::get(f->states)); - } - FSM* f; - PrevState* p; - }; - template struct enter_visitor { enter_visitor(FSM* f_) : f(f_) {} @@ -179,12 +169,15 @@ struct fsm_helper { template using NextState = decltype(std::declval().react(std::declval(), std::declval())); - //! In case a react(CurrentState&, Event) method is found + //! In case a "react(State&, Event) -> NextState" method is found template auto call_trigger(State* current_state) -> NextState { static_assert(not std::is_same, State>::value, "State cannot transition to itself.\n"); auto target_state = f->react(*current_state, std::move(ev)); + f->log_fsm_activity("Detected fsm transition \"%s\" -> \"%s\"", + get_type_name(*current_state).c_str(), + get_type_name(target_state).c_str()); fsm_helper::handle_state_change(f, &target_state, current_state); return target_state; } @@ -192,20 +185,32 @@ struct fsm_helper { template void call_trigger(State* current_state, Args&&... args) { - call_trigger2(current_state); + call_trigger_stage2(current_state); } //! In case a react(CurrentState&, Event) method is not found, but we are in a NestedFSM with a trigger method template - auto call_trigger2(State* s) -> decltype(std::declval().trigger(std::declval())) + auto call_trigger_stage2(State* s) -> decltype(std::declval().trigger(std::declval())) { s->trigger(std::move(ev)); } //! No trigger or react method found. Do nothing - void call_trigger2(...) { f->unhandled_event(std::move(ev)); } + void call_trigger_stage2(...) { f->unhandled_event(std::move(ev)); } FSM* f; Event ev; }; + + template + struct variant_convert { + variant_convert(FSM* f_, PrevState* p_) : f(f_), p(p_) {} + template + void operator()(State& s) + { + handle_state_change(f, &s, p); + } + FSM* f; + PrevState* p; + }; }; } // namespace fsm_details @@ -327,6 +332,27 @@ protected: } } + template + void log_fsm_activity(const char* format, Args&&... args) + { + switch (fsm_event_log_level) { + case LOG_LEVEL_DEBUG: + log_h->debug(format, std::forward(args)...); + break; + case LOG_LEVEL_INFO: + log_h->info(format, std::forward(args)...); + break; + case LOG_LEVEL_WARNING: + log_h->warning(format, std::forward(args)...); + break; + case LOG_LEVEL_ERROR: + log_h->error(format, std::forward(args)...); + break; + default: + break; + } + } + srslte::log_ref log_h; srslte::LOG_LEVEL_ENUM fsm_event_log_level = LOG_LEVEL_DEBUG; }; @@ -390,7 +416,8 @@ public: }; struct complete_st { complete_st(bool success_) : success(success_) {} - bool success; + bool success; + Result result; }; explicit proc_fsm_t(srslte::log_ref log_) : fsm_t(log_) {} diff --git a/lib/test/common/fsm_test.cc b/lib/test/common/fsm_test.cc index 2e311d359..29599d3e7 100644 --- a/lib/test/common/fsm_test.cc +++ b/lib/test/common/fsm_test.cc @@ -56,8 +56,8 @@ public: ~fsm2() { log_h->info("%s being destroyed!", get_type_name(*this).c_str()); } protected: - void enter(state_inner& s) { log_h->info("fsm1::%s::enter called\n", get_type_name().c_str()); } - void exit(state_inner& s) { log_h->info("fsm1::%s::exit called\n", get_type_name().c_str()); } + void enter(state_inner& s) { log_h->info("fsm1::%s::enter called\n", srslte::get_type_name(s).c_str()); } + void exit(state_inner& 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; @@ -72,12 +72,12 @@ protected: template void enter(State& s) { - log_h->info("%s::enter called\n", get_type_name().c_str()); + log_h->info("%s::enter called\n", srslte::get_type_name(s).c_str()); } template void exit(State& s) { - log_h->info("%s::exit called\n", get_type_name().c_str()); + log_h->info("%s::exit called\n", srslte::get_type_name(s).c_str()); } void enter(idle_st& s); void enter(state1& s); @@ -95,12 +95,12 @@ protected: void fsm1::enter(idle_st& s) { - log_h->info("%s::enter custom called\n", get_type_name(s).c_str()); + log_h->info("%s::enter custom called\n", srslte::get_type_name(s).c_str()); idle_enter_counter++; } void fsm1::enter(state1& s) { - log_h->info("%s::enter custom called\n", get_type_name(s).c_str()); + log_h->info("%s::enter custom called\n", srslte::get_type_name(s).c_str()); state1_enter_counter++; } @@ -119,18 +119,18 @@ auto fsm1::fsm2::react(state_inner& s, ev2 e) -> state1 auto fsm1::react(idle_st& s, ev1 e) -> state1 { - log_h->info("%s::react called\n", get_type_name(s).c_str()); + log_h->info("%s::react called\n", srslte::get_type_name(s).c_str()); foo(e); return {}; } auto fsm1::react(state1& s, ev1 e) -> fsm2 { - log_h->info("%s::react called\n", get_type_name(s).c_str()); + log_h->info("%s::react called\n", srslte::get_type_name(s).c_str()); return {this}; } auto fsm1::react(state1& s, ev2 e) -> srslte::choice_t { - log_h->info("%s::react called\n", get_type_name(s).c_str()); + log_h->info("%s::react called\n", srslte::get_type_name(s).c_str()); return idle_st{}; } @@ -162,37 +162,37 @@ int test_hsm() fsm1 f{log_h}; TESTASSERT(f.idle_enter_counter == 1); TESTASSERT(get_type_name(f) == "fsm1"); - TESTASSERT(f.get_state_name() == "fsm1::idle_st"); + TESTASSERT(f.get_state_name() == "idle_st"); TESTASSERT(f.is_in_state()); TESTASSERT(f.foo_counter == 0); // Moving Idle -> State1 ev1 e; f.trigger(e); - TESTASSERT(f.get_state_name() == "fsm1::state1"); + TESTASSERT(f.get_state_name() == "state1"); TESTASSERT(f.is_in_state()); // Moving State1 -> fsm2 f.trigger(e); - TESTASSERT(f.get_state_name() == "fsm1::fsm2"); + TESTASSERT(f.get_state_name() == "fsm2"); TESTASSERT(f.is_in_state()); - TESTASSERT(f.get_state()->get_state_name() == "fsm1::fsm2::state_inner"); + TESTASSERT(f.get_state()->get_state_name() == "state_inner"); // Fsm2 does not listen to ev1 f.trigger(e); - TESTASSERT(std::string{f.get_state_name()} == "fsm1::fsm2"); + TESTASSERT(std::string{f.get_state_name()} == "fsm2"); TESTASSERT(f.is_in_state()); - TESTASSERT(f.get_state()->get_state_name() == "fsm1::fsm2::state_inner"); + TESTASSERT(f.get_state()->get_state_name() == "state_inner"); // Moving fsm2 -> state1 f.trigger(ev2{}); - TESTASSERT(std::string{f.get_state_name()} == "fsm1::state1"); + TESTASSERT(std::string{f.get_state_name()} == "state1"); TESTASSERT(f.is_in_state()); TESTASSERT(f.state1_enter_counter == 2); // Moving state1 -> idle f.trigger(ev2{}); - TESTASSERT(std::string{f.get_state_name()} == "fsm1::idle_st"); + TESTASSERT(std::string{f.get_state_name()} == "idle_st"); TESTASSERT(f.is_in_state()); TESTASSERT(f.foo_counter == 1); TESTASSERT(f.idle_enter_counter == 2); @@ -245,7 +245,7 @@ auto proc1::react(procstate1& s, procevent2 ev) -> complete_st auto proc1::react(complete_st& s, srslte::proc_complete_ev ev) -> idle_st { log_h->info("propagate results %s\n", s.success ? "success" : "failure"); - return {}; //{this}; + return {}; } int test_fsm_proc()