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 "srslte/common/logmap.h"
|
||||||
#include "type_utils.h"
|
#include "type_utils.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -418,9 +419,18 @@ public:
|
||||||
template <typename Ev>
|
template <typename Ev>
|
||||||
bool trigger(Ev&& e)
|
bool trigger(Ev&& e)
|
||||||
{
|
{
|
||||||
fsm_details::trigger_visitor<derived_view, Ev> visitor{derived(), std::forward<Ev>(e)};
|
if (trigger_locked) {
|
||||||
srslte::visit(visitor, derived()->states);
|
pending_events.emplace_back([e](fsm_t<Derived>* d) { d->process_event(e); });
|
||||||
return visitor.result;
|
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>
|
template <typename State>
|
||||||
|
@ -493,8 +503,18 @@ protected:
|
||||||
|
|
||||||
const derived_view* derived() const { return static_cast<const derived_view*>(this); }
|
const derived_view* derived() const { return static_cast<const derived_view*>(this); }
|
||||||
|
|
||||||
|
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_ref log_h;
|
||||||
srslte::LOG_LEVEL_ENUM fsm_event_log_level = LOG_LEVEL_INFO;
|
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>
|
template <typename Derived, typename ParentFSM>
|
||||||
|
|
|
@ -451,6 +451,46 @@ int test_nas_fsm()
|
||||||
return SRSLTE_SUCCESS;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
srslte::log_ref testlog{"TEST"};
|
srslte::log_ref testlog{"TEST"};
|
||||||
|
@ -461,6 +501,8 @@ int main()
|
||||||
testlog->info("TEST \"proc\" finished successfully\n\n");
|
testlog->info("TEST \"proc\" finished successfully\n\n");
|
||||||
TESTASSERT(test_nas_fsm() == SRSLTE_SUCCESS);
|
TESTASSERT(test_nas_fsm() == SRSLTE_SUCCESS);
|
||||||
testlog->info("TEST \"nas fsm\" finished successfully\n\n");
|
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;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue