From 7d49c3c1220c82cc0541e9ba1d4267bd6833bf0a Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Wed, 4 Jun 2025 11:37:53 +0300 Subject: [PATCH] ... --- cxx/mcc_finite_state_machine.h | 83 ++++++++++++++++++++++++++++++++-- cxx/tests/fsm_test.cpp | 40 +++++++++++++++- 2 files changed, 117 insertions(+), 6 deletions(-) diff --git a/cxx/mcc_finite_state_machine.h b/cxx/mcc_finite_state_machine.h index c82ac96..15df69e 100644 --- a/cxx/mcc_finite_state_machine.h +++ b/cxx/mcc_finite_state_machine.h @@ -347,7 +347,7 @@ protected: template void setupInstanceFuncs(FT&& func, std::index_sequence) { - ((_dispatchEventFunc>[this] = std::forward(func)), ...); + (_dispatchEventFunc>.emplace(this, func), ...); (_moveFunc.emplace_back([](MccFiniteStateMachine* from, MccFiniteStateMachine* to) { _dispatchEventFunc>[to] = @@ -451,9 +451,9 @@ public: using all_events_t = deduce_events_t; - // for_each_event([this](EvT) { _eventID.emplace_back(EvT::ID); }); - /* + for_each_event([this](EvT) { _eventID.emplace_back(EvT::ID); }); + for_each_event([states, currentState, this](EvT) mutable { if constexpr (!in_tuple_v) { throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNREGISTERED_EVENT_TYPE); @@ -515,7 +515,8 @@ public: _dispatchEventFunc.erase(inst); }); }); - */ + + setupInstanceFuncs([states, currentState, this](EvT& event) mutable { std::lock_guard lock(_transitionMutex); @@ -561,6 +562,76 @@ public: }, *currentState); }); + */ + + [states, currentState, this](std::index_sequence) { + ((_dispatchEventFunc>[this] = + [states, currentState, this](EvT& event) mutable { + std::lock_guard lock(_transitionMutex); + + std::visit( + [&event, states, currentState, this](curr_state_t*) { + using to_state_t = curr_state_t::transition_t::template find_state_by_event_t; + if constexpr (!std::is_void_v) { + // exit from current + if constexpr (requires(curr_state_t inst) { + { inst.exit(std::declval()) }; + }) { + std::get(*states).exit(event); + } else if constexpr (requires(curr_state_t inst) { + { inst.exit() }; + }) { + std::get(*states).exit(); + } + + // transit ... + if constexpr (requires(EvT inst) { + { inst.onTransit() }; + }) { + event.onTransit(); + } + + *currentState = &std::get(*states); + _currentStateID = to_state_t::ID; + + // enter to new + if constexpr (requires(to_state_t inst) { + { inst.enter(std::declval()) }; + }) { + std::get(*states).enter(event); + } else if constexpr (requires(to_state_t inst) { + { inst.enter() }; + }) { + std::get(*states).enter(); + } + } else { + throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNHANDLED_TRANSITION); + } + }, + *currentState); + }), + ...); + + (_moveFunc.emplace_back([](MccFiniteStateMachine* from, MccFiniteStateMachine* to) { + _dispatchEventFunc>[to] = + std::move(_dispatchEventFunc>[from]); + }), + ...); + + (_copyFunc.emplace_back([](const MccFiniteStateMachine* from, MccFiniteStateMachine* to) { + _dispatchEventFunc>[to] = + _dispatchEventFunc>[from]; + }), + ...); + + (_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) { + // + _dispatchEventFunc>.erase(inst); + }), + ...); + + (_eventID.emplace_back(std::tuple_element_t::ID), ...); + }(std::make_index_sequence>()); std::cout << "MOVE VEC: " << _moveFunc.size() << "\n"; } @@ -595,6 +666,10 @@ public: template auto dispatchEvent(EvT& event) { + if (!_dispatchEventFunc[this]) { + throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNREGISTERED_EVENT_TYPE); + } + _dispatchEventFunc[this](event); } diff --git a/cxx/tests/fsm_test.cpp b/cxx/tests/fsm_test.cpp index e54c8fa..37c1444 100644 --- a/cxx/tests/fsm_test.cpp +++ b/cxx/tests/fsm_test.cpp @@ -30,27 +30,56 @@ struct EV3 { static constexpr std::string_view ID = "EV3"; }; +struct EVN { + static constexpr std::string_view ID = "EVN"; +}; + struct ST1; struct ST2; struct STN { static constexpr std::string_view ID = "STN"; using transition_t = fsm::fsm_transition_table_t, std::pair>; + + void enter() + { + std::cout << "transit to " << ID << "-state\n"; + } + + void exit() + { + std::cout << "transit from " << ID << "-state\n"; + } }; struct ST3 { static constexpr std::string_view ID = "ST3"; using transition_t = fsm::fsm_transition_table_t, std::pair>; + + void enter(EV3& ev) + { + std::cout << "transit to " << ID << "-state\n"; + } + + void exit() + { + std::cout << "transit from " << ID << "-state\n"; + } }; struct ST2 { static constexpr std::string_view ID = "ST2"; using transition_t = fsm::fsm_transition_table_t, std::pair>; - void enter(EV1& ev) + void enter(EV2& ev) { std::cout << "transit to " << ID << "-state\n"; } + + void exit() + { + std::cout << "transit from " << ID << "-state\n"; + } }; struct ST1 { @@ -58,6 +87,11 @@ struct ST1 { using transition_t = fsm::fsm_transition_table_t, std::pair, std::pair, std::pair>; + void enter() + { + std::cout << "transit to " << ID << "-state\n"; + } + void exit() { std::cout << "transit from " << ID << "-state\n"; @@ -151,8 +185,10 @@ int main() std::cout << "\n"; fsmach.dispatchEvent(); - // fsmach.dispatchEvent(); + fsmach.dispatchEvent(); + fsmach.dispatchEvent(); + // fsmach.dispatchEvent(); // using tab_t = fsm::fsm_transition_table_t, std::pair>;