removed namespacing from state printing

This commit is contained in:
Francisco Paisana 2020-04-03 17:47:46 +01:00 committed by Francisco Paisana
parent b699e0e490
commit 8d3427e88a
2 changed files with 71 additions and 44 deletions

View File

@ -31,14 +31,22 @@
#include <memory>
#include <tuple>
namespace srslte {
//! Helper to print the name of a type for logging
#if defined(__GNUC__) && !defined(__clang__)
template <typename T>
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 <typename T>
@ -55,8 +63,6 @@ std::string get_type_name(const T& t)
return get_type_name<T>();
}
namespace srslte {
//! When there is no state transition
struct same_state {
};
@ -102,22 +108,6 @@ struct fsm_helper {
}
static void call_exit(...) {}
template <typename FSM, typename PrevState>
struct variant_convert {
variant_convert(FSM* f_, PrevState* p_) : f(f_), p(p_) {}
template <typename State>
void operator()(State& s)
{
static_assert(not std::is_same<typename std::decay<State>::type, typename std::decay<PrevState>::type>::value,
"State cannot transition to itself.\n");
call_exit(f, &srslte::get<PrevState>(f->states));
f->states.transit(std::move(s));
call_enter(f, &srslte::get<State>(f->states));
}
FSM* f;
PrevState* p;
};
template <typename FSM>
struct enter_visitor {
enter_visitor(FSM* f_) : f(f_) {}
@ -179,12 +169,15 @@ struct fsm_helper {
template <typename State>
using NextState = decltype(std::declval<FSM>().react(std::declval<State&>(), std::declval<Event>()));
//! In case a react(CurrentState&, Event) method is found
//! In case a "react(State&, Event) -> NextState" method is found
template <typename State>
auto call_trigger(State* current_state) -> NextState<State>
{
static_assert(not std::is_same<NextState<State>, 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 <typename State, typename... Args>
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 <typename State>
auto call_trigger2(State* s) -> decltype(std::declval<State>().trigger(std::declval<Event>()))
auto call_trigger_stage2(State* s) -> decltype(std::declval<State>().trigger(std::declval<Event>()))
{
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 <typename FSM, typename PrevState>
struct variant_convert {
variant_convert(FSM* f_, PrevState* p_) : f(f_), p(p_) {}
template <typename State>
void operator()(State& s)
{
handle_state_change(f, &s, p);
}
FSM* f;
PrevState* p;
};
};
} // namespace fsm_details
@ -327,6 +332,27 @@ protected:
}
}
template <typename... Args>
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>(args)...);
break;
case LOG_LEVEL_INFO:
log_h->info(format, std::forward<Args>(args)...);
break;
case LOG_LEVEL_WARNING:
log_h->warning(format, std::forward<Args>(args)...);
break;
case LOG_LEVEL_ERROR:
log_h->error(format, std::forward<Args>(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<Derived>(log_) {}

View File

@ -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<state_inner>().c_str()); }
void exit(state_inner& s) { log_h->info("fsm1::%s::exit called\n", get_type_name<state_inner>().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 <typename State>
void enter(State& s)
{
log_h->info("%s::enter called\n", get_type_name<State>().c_str());
log_h->info("%s::enter called\n", srslte::get_type_name(s).c_str());
}
template <typename State>
void exit(State& s)
{
log_h->info("%s::exit called\n", get_type_name<State>().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<idle_st, 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 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<fsm1::idle_st>());
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<fsm1::state1>());
// Moving State1 -> fsm2
f.trigger(e);
TESTASSERT(f.get_state_name() == "fsm1::fsm2");
TESTASSERT(f.get_state_name() == "fsm2");
TESTASSERT(f.is_in_state<fsm1::fsm2>());
TESTASSERT(f.get_state<fsm1::fsm2>()->get_state_name() == "fsm1::fsm2::state_inner");
TESTASSERT(f.get_state<fsm1::fsm2>()->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<fsm1::fsm2>());
TESTASSERT(f.get_state<fsm1::fsm2>()->get_state_name() == "fsm1::fsm2::state_inner");
TESTASSERT(f.get_state<fsm1::fsm2>()->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<fsm1::state1>());
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<fsm1::idle_st>());
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<bool> ev) -> idle_st
{
log_h->info("propagate results %s\n", s.success ? "success" : "failure");
return {}; //{this};
return {};
}
int test_fsm_proc()