mirror of https://github.com/PentHertz/srsLTE.git
enter/exit are now being called in order
This commit is contained in:
parent
2e15514d00
commit
1aae510e9d
|
@ -401,8 +401,8 @@ bool holds_alternative(const Choice& u)
|
||||||
return u.template is<T>();
|
return u.template is<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Choice>
|
template <typename T, typename... Args>
|
||||||
T* get_if(Choice& c)
|
T* get_if(choice_t<Args...>& c)
|
||||||
{
|
{
|
||||||
return c.template get_if<T>();
|
return c.template get_if<T>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@ namespace srslte {
|
||||||
// using same_state = mpark::monostate;
|
// using same_state = mpark::monostate;
|
||||||
struct same_state {
|
struct same_state {
|
||||||
};
|
};
|
||||||
template <typename... Args>
|
|
||||||
using state_list = choice_t<Args...>;
|
|
||||||
|
|
||||||
namespace fsm_details {
|
namespace fsm_details {
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ struct variant_convert {
|
||||||
if (p != nullptr) {
|
if (p != nullptr) {
|
||||||
srslte::get<PrevState>(*v).exit();
|
srslte::get<PrevState>(*v).exit();
|
||||||
}
|
}
|
||||||
*v = std::move(s);
|
v->transit(std::move(s));
|
||||||
srslte::get<State>(*v).enter();
|
srslte::get<State>(*v).enter();
|
||||||
}
|
}
|
||||||
TargetVariant* v;
|
TargetVariant* v;
|
||||||
|
@ -76,6 +74,14 @@ struct fsm_helper {
|
||||||
template <typename FSM, typename State>
|
template <typename FSM, typename State>
|
||||||
using disable_if_fsm_state = typename get_fsm_state_list<FSM>::template disable_if_can_hold<State>;
|
using disable_if_fsm_state = typename get_fsm_state_list<FSM>::template disable_if_can_hold<State>;
|
||||||
|
|
||||||
|
struct enter_visitor {
|
||||||
|
template <typename State>
|
||||||
|
void operator()(State&& s)
|
||||||
|
{
|
||||||
|
s.do_enter();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//! Stayed in same state
|
//! Stayed in same state
|
||||||
template <typename FSM, typename PrevState>
|
template <typename FSM, typename PrevState>
|
||||||
static void handle_state_change(FSM* f, same_state* s, PrevState* p)
|
static void handle_state_change(FSM* f, same_state* s, PrevState* p)
|
||||||
|
@ -97,8 +103,8 @@ struct fsm_helper {
|
||||||
if (p != nullptr) {
|
if (p != nullptr) {
|
||||||
srslte::get<PrevState>(f->states).exit();
|
srslte::get<PrevState>(f->states).exit();
|
||||||
}
|
}
|
||||||
f->states = std::move(*s);
|
f->states.transit(std::move(*s));
|
||||||
srslte::get<State>(f->states).enter();
|
srslte::get<State>(f->states).do_enter();
|
||||||
}
|
}
|
||||||
//! State not present in current FSM. Attempt state transition in parent FSM in the case of NestedFSM
|
//! State not present in current FSM. Attempt state transition in parent FSM in the case of NestedFSM
|
||||||
template <typename FSM, typename State, typename PrevState>
|
template <typename FSM, typename State, typename PrevState>
|
||||||
|
@ -164,6 +170,10 @@ class state_t
|
||||||
public:
|
public:
|
||||||
state_t() = default;
|
state_t() = default;
|
||||||
virtual const char* name() const = 0;
|
virtual const char* name() const = 0;
|
||||||
|
void do_enter() { enter(); }
|
||||||
|
void do_exit() { exit(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
virtual void enter() {}
|
virtual void enter() {}
|
||||||
virtual void exit() {}
|
virtual void exit() {}
|
||||||
};
|
};
|
||||||
|
@ -185,6 +195,24 @@ protected:
|
||||||
public:
|
public:
|
||||||
static const bool is_nested = false;
|
static const bool is_nested = false;
|
||||||
|
|
||||||
|
template <typename... States>
|
||||||
|
struct state_list : public choice_t<States...> {
|
||||||
|
using base_t = choice_t<States...>;
|
||||||
|
template <typename... Args>
|
||||||
|
state_list(Args&&... args) : base_t(std::forward<Args>(args)...)
|
||||||
|
{
|
||||||
|
if (not Derived::is_nested) {
|
||||||
|
fsm_details::fsm_helper::enter_visitor visitor{};
|
||||||
|
this->visit(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename State>
|
||||||
|
void transit(State&& s)
|
||||||
|
{
|
||||||
|
this->template emplace<State>(std::forward<State>(s));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Push Events to FSM
|
// Push Events to FSM
|
||||||
template <typename Ev>
|
template <typename Ev>
|
||||||
void trigger(Ev&& e)
|
void trigger(Ev&& e)
|
||||||
|
@ -225,6 +253,13 @@ protected:
|
||||||
// Access to CRTP derived class
|
// Access to CRTP derived class
|
||||||
derived_view* derived() { return static_cast<derived_view*>(this); }
|
derived_view* derived() { return static_cast<derived_view*>(this); }
|
||||||
const derived_view* derived() const { return static_cast<const derived_view*>(this); }
|
const derived_view* derived() const { return static_cast<const derived_view*>(this); }
|
||||||
|
|
||||||
|
void do_enter()
|
||||||
|
{
|
||||||
|
enter();
|
||||||
|
fsm_details::fsm_helper::enter_visitor visitor{};
|
||||||
|
derived()->states.visit(visitor);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Derived, typename ParentFSM>
|
template <typename Derived, typename ParentFSM>
|
||||||
|
|
|
@ -79,19 +79,19 @@ public:
|
||||||
auto react(state_inner& s, ev2 e) -> state1;
|
auto react(state_inner& s, ev2 e) -> state1;
|
||||||
|
|
||||||
// list of states
|
// list of states
|
||||||
srslte::state_list<state_inner> states;
|
state_list<state_inner> states;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// transitions
|
// transitions
|
||||||
auto react(idle_st& s, ev1 e) -> state1;
|
auto react(idle_st& s, ev1 e) -> state1;
|
||||||
auto react(state1& s, ev1 e) -> fsm2;
|
auto react(state1& s, ev1 e) -> fsm2;
|
||||||
auto react(state1& s, ev2 e) -> srslte::state_list<idle_st, fsm2>;
|
auto react(state1& s, ev2 e) -> srslte::choice_t<idle_st, fsm2>;
|
||||||
|
|
||||||
void foo(ev1 e) { foo_counter++; }
|
void foo(ev1 e) { foo_counter++; }
|
||||||
|
|
||||||
// list of states
|
// list of states
|
||||||
srslte::state_list<idle_st, state1, fsm2> states{idle_st{this}};
|
state_list<idle_st, state1, fsm2> states{idle_st{this}};
|
||||||
};
|
};
|
||||||
|
|
||||||
// FSM event handlers
|
// FSM event handlers
|
||||||
|
@ -118,7 +118,7 @@ auto fsm1::react(state1& s, ev1 e) -> fsm2
|
||||||
test_log->info("fsm1::%s::react called\n", s.name());
|
test_log->info("fsm1::%s::react called\n", s.name());
|
||||||
return fsm2{this};
|
return fsm2{this};
|
||||||
}
|
}
|
||||||
auto fsm1::react(state1& s, ev2 e) -> srslte::state_list<idle_st, fsm2>
|
auto fsm1::react(state1& s, ev2 e) -> srslte::choice_t<idle_st, fsm2>
|
||||||
{
|
{
|
||||||
test_log->info("fsm1::%s::react called\n", s.name());
|
test_log->info("fsm1::%s::react called\n", s.name());
|
||||||
return idle_st{this};
|
return idle_st{this};
|
||||||
|
@ -130,7 +130,7 @@ namespace srslte {
|
||||||
namespace fsm_details {
|
namespace fsm_details {
|
||||||
|
|
||||||
static_assert(std::is_same<fsm_helper::get_fsm_state_list<fsm1>,
|
static_assert(std::is_same<fsm_helper::get_fsm_state_list<fsm1>,
|
||||||
srslte::state_list<fsm1::idle_st, fsm1::state1, fsm1::fsm2> >::value,
|
fsm1::state_list<fsm1::idle_st, fsm1::state1, fsm1::fsm2> >::value,
|
||||||
"get state list failed\n");
|
"get state list failed\n");
|
||||||
static_assert(std::is_same<fsm_helper::enable_if_fsm_state<fsm1, fsm1::idle_st>, void>::value,
|
static_assert(std::is_same<fsm_helper::enable_if_fsm_state<fsm1, fsm1::idle_st>, void>::value,
|
||||||
"get state list failed\n");
|
"get state list failed\n");
|
||||||
|
|
Loading…
Reference in New Issue