cleanups in MccFiniteStateMachine
This commit is contained in:
parent
7d49c3c122
commit
04e9f84315
@ -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,11 +88,10 @@ 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 {
|
||||
requires std::same_as<const std::string_view, decltype(T::ID)>;
|
||||
typename T::transition_t;
|
||||
};
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
// concept for std::pair
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user