This commit is contained in:
Timur A. Fatkhullin 2025-06-09 18:24:28 +03:00
parent 04e9f84315
commit 88e45886b2
2 changed files with 33 additions and 39 deletions

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include <cxxabi.h> /* MOUNT CONTROL COMPONENTS LIBRARY */
#include <iostream>
/* FINITE-STATE MACHINE IMPLEMENTATION */
#include <concepts> #include <concepts>
#include <functional> #include <functional>
@ -17,6 +19,8 @@
namespace mcc::fsm namespace mcc::fsm
{ {
/* error codes enum definition */
enum class MccFiniteStateMachineErrorCode : int { ERROR_OK, ERROR_UNREGISTERED_EVENT_TYPE, ERROR_UNHANDLED_TRANSITION }; enum class MccFiniteStateMachineErrorCode : int { ERROR_OK, ERROR_UNREGISTERED_EVENT_TYPE, ERROR_UNHANDLED_TRANSITION };
} // namespace mcc::fsm } // namespace mcc::fsm
@ -24,10 +28,12 @@ enum class MccFiniteStateMachineErrorCode : int { ERROR_OK, ERROR_UNREGISTERED_E
namespace std namespace std
{ {
template <> template <>
class is_error_code_enum<mcc::fsm::MccFiniteStateMachineErrorCode> : public true_type class is_error_code_enum<mcc::fsm::MccFiniteStateMachineErrorCode> : public true_type
{ {
}; };
} // namespace std } // namespace std
@ -35,6 +41,8 @@ namespace mcc::fsm
{ {
/* error category definition */
// error category // error category
struct MccFiniteStateMachineCategory : public std::error_category { struct MccFiniteStateMachineCategory : public std::error_category {
MccFiniteStateMachineCategory() : std::error_category() {} MccFiniteStateMachineCategory() : std::error_category() {}
@ -85,7 +93,7 @@ concept fsm_event_c = requires { requires std::same_as<const std::string_view, d
/* /*
The only requirements to State-class is public-accepted static constant 'ID' and The only requirements to State-class is public-accepted static constant 'ID' and
definition of type transition_table_t definition of type transition_t
*/ */
template <typename T> template <typename T>
concept fsm_state_c = std::is_default_constructible_v<T> && requires { concept fsm_state_c = std::is_default_constructible_v<T> && requires {
@ -111,7 +119,10 @@ concept fsm_tuple_of_events_c =
} // namespace traits } // namespace traits
/* Event-to-State transition table definition */ /*
* Event-to-State transition table definition
* (I do not use here concepts from the above traits to avoid possible recursive concept problem)
*/
template <traits::fsm_pair_of_types_c... PTs> template <traits::fsm_pair_of_types_c... PTs>
struct fsm_transition_table_t; struct fsm_transition_table_t;
@ -181,6 +192,11 @@ public:
}; };
/*
* Finite-state machine definition
* (an idea is from https://codeberg.org/cmargiotta/compile-time-fsm)
*/
class MccFiniteStateMachine class MccFiniteStateMachine
{ {
protected: protected:
@ -298,10 +314,10 @@ protected:
std::vector<std::function<void(const MccFiniteStateMachine*)>> _destroyFunc{}; std::vector<std::function<void(const MccFiniteStateMachine*)>> _destroyFunc{};
std::string_view _currentStateID; std::string_view _currentStateID;
std::vector<std::string_view> _stateID; std::vector<std::string_view> _stateID{};
std::vector<std::string_view> _eventID; std::vector<std::string_view> _eventID{};
std::mutex _transitionMutex; std::mutex _transitionMutex{};
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to) static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
@ -350,30 +366,6 @@ public:
return std::vector<std::string_view>({STs::ID...}); return std::vector<std::string_view>({STs::ID...});
}(*states); }(*states);
int status;
char* aa = abi::__cxa_demangle(typeid(states_t).name(), NULL, NULL, &status);
std::cout << "deduced states_t = " << aa << '\n';
free(aa);
aa = abi::__cxa_demangle(typeid(typename InitStateT::transition_t::event_state_pair_t).name(), NULL, NULL,
&status);
std::cout << "event_state_pair_t = " << aa << '\n';
free(aa);
aa = abi::__cxa_demangle(typeid(typename InitStateT::transition_t::events_t).name(), NULL, NULL, &status);
std::cout << "events_t = " << aa << '\n';
free(aa);
aa =
abi::__cxa_demangle(typeid(typename InitStateT::transition_t::unique_states_t).name(), NULL, NULL, &status);
std::cout << "unique_states_t = " << aa << '\n';
free(aa);
aa = abi::__cxa_demangle(typeid(deduce_events_t<InitStateT>).name(), NULL, NULL, &status);
std::cout << "deduced events_t = " << aa << '\n';
free(aa);
// setup dispatch event functions // setup dispatch event functions
@ -446,8 +438,6 @@ public:
(_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...); (_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...);
}(std::make_index_sequence<std::tuple_size_v<all_events_t>>()); }(std::make_index_sequence<std::tuple_size_v<all_events_t>>());
std::cout << "MOVE VEC: " << _moveFunc.size() << "\n";
} }
MccFiniteStateMachine(const MccFiniteStateMachine& other) MccFiniteStateMachine(const MccFiniteStateMachine& other)
@ -501,6 +491,8 @@ public:
} }
// returns IDs of all deduced unique states
template <mcc::traits::mcc_range_of_input_char_range R> template <mcc::traits::mcc_range_of_input_char_range R>
R stateIDs() const R stateIDs() const
{ {
@ -518,6 +510,8 @@ public:
} }
// returns IDs of all deduced events
template <mcc::traits::mcc_range_of_input_char_range R> template <mcc::traits::mcc_range_of_input_char_range R>
R eventIDs() const R eventIDs() const
{ {

View File

@ -190,14 +190,14 @@ int main()
// fsmach.dispatchEvent<EVN>(); // fsmach.dispatchEvent<EVN>();
// using tab_t = fsm::fsm_transition_table_t<std::pair<EV1, ST2>, std::pair<EV3, ST1>>; using tab_t = fsm::fsm_transition_table_t<std::pair<EV1, ST2>, std::pair<EV3, ST1>>;
// using st_t = tab_t::find_state_by_event_t<EV2>; using st_t = tab_t::find_state_by_event_t<EV2>;
// int status; int status;
// char* aa = abi::__cxa_demangle(typeid(st_t).name(), NULL, NULL, &status); char* aa = abi::__cxa_demangle(typeid(st_t).name(), NULL, NULL, &status);
// std::cout << "aa = " << aa << "\n"; std::cout << "aa = " << aa << "\n";
// free(aa); free(aa);
return 0; return 0;