mirror of https://github.com/PentHertz/srsLTE.git
add ability for fsms to self-trigger
This commit is contained in:
parent
9f98bb3f54
commit
12dda03bb8
|
@ -25,6 +25,7 @@
|
|||
#include "srslte/common/logmap.h"
|
||||
#include "type_utils.h"
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
@ -418,9 +419,18 @@ public:
|
|||
template <typename Ev>
|
||||
bool trigger(Ev&& e)
|
||||
{
|
||||
fsm_details::trigger_visitor<derived_view, Ev> visitor{derived(), std::forward<Ev>(e)};
|
||||
srslte::visit(visitor, derived()->states);
|
||||
return visitor.result;
|
||||
if (trigger_locked) {
|
||||
pending_events.emplace_back([e](fsm_t<Derived>* d) { d->process_event(e); });
|
||||
return false;
|
||||
}
|
||||
trigger_locked = true;
|
||||
bool ret = process_event(std::forward<Ev>(e));
|
||||
while (not pending_events.empty()) {
|
||||
pending_events.front()(this);
|
||||
pending_events.pop_front();
|
||||
}
|
||||
trigger_locked = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename State>
|
||||
|
@ -493,8 +503,18 @@ protected:
|
|||
|
||||
const derived_view* derived() const { return static_cast<const derived_view*>(this); }
|
||||
|
||||
srslte::log_ref log_h;
|
||||
srslte::LOG_LEVEL_ENUM fsm_event_log_level = LOG_LEVEL_INFO;
|
||||
template <typename Ev>
|
||||
bool process_event(Ev&& e)
|
||||
{
|
||||
fsm_details::trigger_visitor<derived_view, Ev> visitor{derived(), std::forward<Ev>(e)};
|
||||
srslte::visit(visitor, derived()->states);
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
srslte::log_ref log_h;
|
||||
srslte::LOG_LEVEL_ENUM fsm_event_log_level = LOG_LEVEL_INFO;
|
||||
bool trigger_locked = false;
|
||||
std::deque<std::function<void(fsm_t<Derived>*)> > pending_events;
|
||||
};
|
||||
|
||||
template <typename Derived, typename ParentFSM>
|
||||
|
|
|
@ -451,6 +451,46 @@ int test_nas_fsm()
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
struct fsm3 : public srslte::fsm_t<fsm3> {
|
||||
struct st1 {};
|
||||
struct st2 {
|
||||
int counter = 0;
|
||||
void enter(fsm3* fsm) { counter++; }
|
||||
};
|
||||
|
||||
fsm3() : base_t(srslte::log_ref{"TEST"}) {}
|
||||
|
||||
protected:
|
||||
void handle_ev1(st1& s, st2& d, const ev1& ev) { trigger(ev2{}); }
|
||||
void handle_ev2(st2& s, st1& d, const ev2& ev)
|
||||
{
|
||||
if (s.counter < 2) {
|
||||
trigger(ev1{});
|
||||
}
|
||||
}
|
||||
|
||||
state_list<st1, st2> states{this};
|
||||
// clang-format off
|
||||
using transitions = transition_table<
|
||||
// Start Target Event Action
|
||||
// +------------------------+-------------------------+-------------------+--------------------+
|
||||
row< st1, st2, ev1, &fsm3::handle_ev1>,
|
||||
row< st2, st1, ev2, &fsm3::handle_ev2>
|
||||
>;
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
int test_fsm_self_trigger()
|
||||
{
|
||||
fsm3 fsm;
|
||||
|
||||
TESTASSERT(fsm.is_in_state<fsm3::st1>());
|
||||
fsm.trigger(ev1{});
|
||||
TESTASSERT(fsm.is_in_state<fsm3::st1>());
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
srslte::log_ref testlog{"TEST"};
|
||||
|
@ -461,6 +501,8 @@ int main()
|
|||
testlog->info("TEST \"proc\" finished successfully\n\n");
|
||||
TESTASSERT(test_nas_fsm() == SRSLTE_SUCCESS);
|
||||
testlog->info("TEST \"nas fsm\" finished successfully\n\n");
|
||||
TESTASSERT(test_fsm_self_trigger() == SRSLTE_SUCCESS);
|
||||
testlog->info("TEST \"fsm self trigger\" finished successfully\n\n");
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue