This commit is contained in:
Timur A. Fatkhullin
2025-06-17 00:46:13 +03:00
parent 64a3544bd8
commit 02afd65d6f
5 changed files with 69 additions and 60 deletions

View File

@@ -317,7 +317,7 @@ protected:
std::vector<std::string_view> _stateID{};
std::vector<std::string_view> _eventID{};
std::mutex _transitionMutex{};
std::recursive_mutex _transitionMutex{};
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
@@ -385,18 +385,23 @@ public:
[states, currentState, this]<size_t... Is>(std::index_sequence<Is...>) {
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) {
std::lock_guard lock(_transitionMutex);
// to avoid effects of possible compiler optimizations
// (here one needs to be sure that inside the lambda 'event' is used by reference)
const auto p_event = &event;
std::visit(
[&event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
[p_event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
using to_state_t = curr_state_t::transition_t::template find_state_by_event_t<EvT>;
if constexpr (!std::is_void_v<to_state_t>) {
std::lock_guard lock(_transitionMutex);
// exit from current
if constexpr (requires(curr_state_t inst) {
{ inst.exit(std::declval<EvT&>()) };
}) {
std::get<curr_state_t>(*states).exit(event);
// std::get<curr_state_t>(*states).exit(event);
std::get<curr_state_t>(*states).exit(*p_event);
} else if constexpr (requires(curr_state_t inst) {
{ inst.exit() };
}) {
@@ -407,7 +412,8 @@ public:
if constexpr (requires(EvT inst) {
{ inst.onTransit() };
}) {
event.onTransit();
// event.onTransit();
p_event->onTransit();
}
*currentState = &std::get<to_state_t>(*states);
@@ -417,7 +423,8 @@ public:
if constexpr (requires(to_state_t inst) {
{ inst.enter(std::declval<EvT&>()) };
}) {
std::get<to_state_t>(*states).enter(event);
// std::get<to_state_t>(*states).enter(event);
std::get<to_state_t>(*states).enter(*p_event);
} else if constexpr (requires(to_state_t inst) {
{ inst.enter() };
}) {
@@ -450,6 +457,17 @@ public:
(_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...);
}(std::make_index_sequence<std::tuple_size_v<all_events_t>>());
// call enter() method (if it exists) of the initial state
std::visit(
[]<traits::fsm_state_c curr_state_t>(curr_state_t* cstate) {
if constexpr (requires(curr_state_t inst) {
{ inst.enter() };
}) {
cstate->enter();
}
},
*currentState);
}
MccFiniteStateMachine(const MccFiniteStateMachine& other)