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());
|
return std::error_code(static_cast<int>(ec), MccFiniteStateMachineCategory::get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace traits
|
namespace traits
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -82,8 +80,7 @@ namespace traits
|
|||||||
The only requirement to Event-class is public-accepted static constant 'ID'
|
The only requirement to Event-class is public-accepted static constant 'ID'
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept fsm_event_c = std::is_default_constructible_v<T> && std::is_move_constructible_v<T> && std::movable<T> &&
|
concept fsm_event_c = requires { requires std::same_as<const std::string_view, decltype(T::ID)>; };
|
||||||
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
|
definition of type transition_table_t
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept fsm_state_c =
|
concept fsm_state_c = std::is_default_constructible_v<T> && requires {
|
||||||
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)>;
|
||||||
requires std::same_as<const std::string_view, decltype(T::ID)>;
|
typename T::transition_t;
|
||||||
typename T::transition_t;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// concept for std::pair
|
// concept for std::pair
|
||||||
@ -282,42 +278,6 @@ protected:
|
|||||||
using variant_from_tuple_t = typename variant_from_tuple<TplT>::variant_t;
|
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
|
// check if given event-type is in std::tuple of event-types
|
||||||
template <traits::fsm_event_c EvT, typename EvTplT>
|
template <traits::fsm_event_c EvT, typename EvTplT>
|
||||||
struct in_tuple;
|
struct in_tuple;
|
||||||
@ -344,38 +304,6 @@ protected:
|
|||||||
std::mutex _transitionMutex;
|
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)
|
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
|
||||||
{
|
{
|
||||||
if (from != to) {
|
if (from != to) {
|
||||||
@ -451,119 +379,6 @@ public:
|
|||||||
|
|
||||||
using all_events_t = deduce_events_t<InitStateT>;
|
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...>) {
|
[states, currentState, this]<size_t... Is>(std::index_sequence<Is...>) {
|
||||||
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
|
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
|
||||||
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) mutable {
|
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) mutable {
|
||||||
@ -625,7 +440,6 @@ public:
|
|||||||
...);
|
...);
|
||||||
|
|
||||||
(_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) {
|
(_destroyFunc.emplace_back([](const MccFiniteStateMachine* inst) {
|
||||||
//
|
|
||||||
_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>.erase(inst);
|
_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>.erase(inst);
|
||||||
}),
|
}),
|
||||||
...);
|
...);
|
||||||
@ -675,6 +489,7 @@ public:
|
|||||||
|
|
||||||
template <traits::fsm_event_c EvT>
|
template <traits::fsm_event_c EvT>
|
||||||
auto dispatchEvent()
|
auto dispatchEvent()
|
||||||
|
requires std::default_initializable<EvT>
|
||||||
{
|
{
|
||||||
static EvT event;
|
static EvT event;
|
||||||
return dispatchEvent(event);
|
return dispatchEvent(event);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user