cleanups in MccFiniteStateMachine

This commit is contained in:
Timur A. Fatkhullin 2025-06-04 17:13:50 +03:00
parent 7d49c3c122
commit 04e9f84315

View File

@ -73,8 +73,6 @@ inline std::error_code make_error_code(MccFiniteStateMachineErrorCode ec)
return std::error_code(static_cast<int>(ec), MccFiniteStateMachineCategory::get());
}
namespace traits
{
@ -82,8 +80,7 @@ namespace traits
The only requirement to Event-class is public-accepted static constant 'ID'
*/
template <typename T>
concept fsm_event_c = std::is_default_constructible_v<T> && std::is_move_constructible_v<T> && std::movable<T> &&
requires { requires std::same_as<const std::string_view, decltype(T::ID)>; };
concept fsm_event_c = requires { requires std::same_as<const std::string_view, decltype(T::ID)>; };
/*
@ -91,8 +88,7 @@ concept fsm_event_c = std::is_default_constructible_v<T> && std::is_move_constru
definition of type transition_table_t
*/
template <typename T>
concept fsm_state_c =
std::is_default_constructible_v<T> && std::is_move_constructible_v<T> && std::movable<T> && requires {
concept fsm_state_c = std::is_default_constructible_v<T> && requires {
requires std::same_as<const std::string_view, decltype(T::ID)>;
typename T::transition_t;
};
@ -282,42 +278,6 @@ protected:
using variant_from_tuple_t = typename variant_from_tuple<TplT>::variant_t;
// call given function for all event-types in the given std::tuple
template <traits::fsm_tuple_of_events_c EvTplT, typename FT, size_t... Is>
static void for_each_event(FT&& func, std::index_sequence<Is...>)
{
(func(std::get<Is>(EvTplT{})), ...);
};
template <traits::fsm_tuple_of_events_c EvTplT, typename FT>
static void for_each_event(FT&& func)
{
for_each_event<EvTplT>(std::forward<FT>(func), std::make_index_sequence<std::tuple_size_v<EvTplT>>());
};
template <traits::fsm_state_c StT, typename FT>
static void for_each_event_in_each_state(FT&& func)
{
for_each_event<typename StT::transition_t::events_t>(std::forward<FT>(func));
}
template <typename StTplT, typename FT, size_t... Is>
static void for_each_event_in_each_state(FT&& func, std::index_sequence<Is...>)
{
(for_each_event_in_each_state<std::tuple_element_t<Is, StTplT>>(std::forward<FT>(func)), ...);
}
template <typename StTplT, typename FT>
static void for_each_event_in_each_state(FT&& func)
{
for_each_event_in_each_state<StTplT>(std::forward<FT>(func),
std::make_index_sequence<std::tuple_size_v<StTplT>>());
}
// check if given event-type is in std::tuple of event-types
template <traits::fsm_event_c EvT, typename EvTplT>
struct in_tuple;
@ -344,38 +304,6 @@ protected:
std::mutex _transitionMutex;
template <traits::fsm_tuple_of_events_c EvTplT, typename FT, size_t... Is>
void setupInstanceFuncs(FT&& func, std::index_sequence<Is...>)
{
(_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>.emplace(this, func), ...);
(_moveFunc.emplace_back([](MccFiniteStateMachine* from, MccFiniteStateMachine* to) {
_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>[to] =
std::move(_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>[from]);
}),
...);
(_copyFunc.emplace_back([](const MccFiniteStateMachine* from, MccFiniteStateMachine* to) {
_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>[to] =
_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>[from];
}),
...);
(_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) {
//
_dispatchEventFunc<std::tuple_element_t<Is, EvTplT>>.erase(inst);
}),
...);
(_eventID.emplace_back(std::tuple_element_t<Is, EvTplT>::ID), ...);
};
template <traits::fsm_tuple_of_events_c EvTplT, typename FT>
void setupInstanceFuncs(FT&& func)
{
setupInstanceFuncs<EvTplT>(std::forward<FT>(func), std::make_index_sequence<std::tuple_size_v<EvTplT>>());
};
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
{
if (from != to) {
@ -451,119 +379,6 @@ public:
using all_events_t = deduce_events_t<InitStateT>;
/*
for_each_event<all_events_t>([this]<traits::fsm_event_c EvT>(EvT) { _eventID.emplace_back(EvT::ID); });
for_each_event<all_events_t>([states, currentState, this]<traits::fsm_event_c EvT>(EvT) mutable {
if constexpr (!in_tuple_v<EvT, all_events_t>) {
throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNREGISTERED_EVENT_TYPE);
}
_dispatchEventFunc<EvT>[this] = [states, currentState, this](EvT& event) mutable {
std::lock_guard lock(_transitionMutex);
std::visit(
[&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>) {
// exit from current
if constexpr (requires(curr_state_t inst) {
{ inst.exit(std::declval<EvT&>()) };
}) {
std::get<curr_state_t>(*states).exit(event);
} else if constexpr (requires(curr_state_t inst) {
{ inst.exit() };
}) {
std::get<curr_state_t>(*states).exit();
}
// transit ...
if constexpr (requires(EvT inst) {
{ inst.onTransit() };
}) {
event.onTransit();
}
*currentState = &std::get<to_state_t>(*states);
_currentStateID = to_state_t::ID;
// enter to new
if constexpr (requires(to_state_t inst) {
{ inst.enter(std::declval<EvT&>()) };
}) {
std::get<to_state_t>(*states).enter(event);
} else if constexpr (requires(to_state_t inst) {
{ inst.enter() };
}) {
std::get<to_state_t>(*states).enter();
}
} else {
throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNHANDLED_TRANSITION);
}
},
*currentState);
};
_moveFunc.emplace_back([](MccFiniteStateMachine* from, MccFiniteStateMachine* to) {
_dispatchEventFunc<EvT>[to] = std::move(_dispatchEventFunc<EvT>[from]);
});
_copyFunc.emplace_back([](const MccFiniteStateMachine* from, MccFiniteStateMachine* to) {
_dispatchEventFunc<EvT>[to] = _dispatchEventFunc<EvT>[from];
});
_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) {
//
_dispatchEventFunc<EvT>.erase(inst);
});
});
setupInstanceFuncs<all_events_t>([states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) mutable {
std::lock_guard lock(_transitionMutex);
std::visit(
[&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>) {
// exit from current
if constexpr (requires(curr_state_t inst) {
{ inst.exit(std::declval<EvT&>()) };
}) {
std::get<curr_state_t>(*states).exit(event);
} else if constexpr (requires(curr_state_t inst) {
{ inst.exit() };
}) {
std::get<curr_state_t>(*states).exit();
}
// transit ...
if constexpr (requires(EvT inst) {
{ inst.onTransit() };
}) {
event.onTransit();
}
*currentState = &std::get<to_state_t>(*states);
_currentStateID = to_state_t::ID;
// enter to new
if constexpr (requires(to_state_t inst) {
{ inst.enter(std::declval<EvT&>()) };
}) {
std::get<to_state_t>(*states).enter(event);
} else if constexpr (requires(to_state_t inst) {
{ inst.enter() };
}) {
std::get<to_state_t>(*states).enter();
}
} else {
throw std::system_error(MccFiniteStateMachineErrorCode::ERROR_UNHANDLED_TRANSITION);
}
},
*currentState);
});
*/
[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) mutable {
@ -625,7 +440,6 @@ public:
...);
(_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) {
//
_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>.erase(inst);
}),
...);
@ -675,6 +489,7 @@ public:
template <traits::fsm_event_c EvT>
auto dispatchEvent()
requires std::default_initializable<EvT>
{
static EvT event;
return dispatchEvent(event);