This commit is contained in:
Timur A. Fatkhullin 2025-06-02 02:10:57 +03:00
parent e069ed84f0
commit 9bee1ca0ea

View File

@ -238,6 +238,40 @@ protected:
template <traits::fsm_event_c EvT> template <traits::fsm_event_c EvT>
inline static std::unordered_map<const MccFiniteStateMachine*, std::function<void(EvT&)>> _dispatchEventFunc{}; inline static std::unordered_map<const MccFiniteStateMachine*, std::function<void(EvT&)>> _dispatchEventFunc{};
std::vector<std::function<void(MccFiniteStateMachine*, MccFiniteStateMachine*)>> _moveFunc{};
std::vector<std::function<void(const MccFiniteStateMachine*, MccFiniteStateMachine*)>> _copyFunc{};
std::vector<std::function<void()>> _destroyFunc{};
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
{
if (from != to) {
for (auto& func : from->_copyFunc) {
func(from, to);
}
to->_moveFunc = from->_moveFunc;
to->_copyFunc = from->_copyFunc;
to->_destroyFunc = from->_destroyFunc;
}
return *to;
}
static MccFiniteStateMachine& moveInstance(MccFiniteStateMachine* from, MccFiniteStateMachine* to)
{
if (from != to) {
for (auto& func : from->_moveFunc) {
func(from, to);
}
to->_moveFunc = std::move(from->_moveFunc);
to->_copyFunc = std::move(from->_copyFunc);
to->_destroyFunc = std::move(from->_destroyFunc);
}
return *to;
}
public: public:
template <traits::fsm_state_c InitStateT> template <traits::fsm_state_c InitStateT>
MccFiniteStateMachine(InitStateT) MccFiniteStateMachine(InitStateT)
@ -277,47 +311,71 @@ public:
for_each_event<deduce_events_t<InitStateT>>([states, currentState, this]<traits::fsm_event_c EvT>(EvT) mutable { for_each_event<deduce_events_t<InitStateT>>([states, currentState, this]<traits::fsm_event_c EvT>(EvT) mutable {
_dispatchEventFunc<EvT>[this] = [states, currentState, this](EvT& event) mutable { _dispatchEventFunc<EvT>[this] = [states, currentState, this](EvT& event) mutable {
std::visit( std::visit(
[&event, states]<traits::fsm_state_c curr_state_t>(curr_state_t*) { [&event, states, currentState]<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>; 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>) { if constexpr (!std::is_void_v<to_state_t>) {
/// throw?!! // exit from current
return; 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();
}
// exit from current // transit ...
if constexpr (requires(curr_state_t inst) { if constexpr (requires(EvT inst) {
{ inst.exit(std::declval<EvT>()) }; { inst.on_transit() };
}) { }) {
std::get<curr_state_t>(states).exit(event); event.on_transit();
} else if constexpr (requires(curr_state_t inst) { }
{ inst.exit() };
}) {
std::get<curr_state_t>(states).exit();
}
// transit ... *currentState = std::get<to_state_t*>(*states);
if constexpr (requires(EvT inst) {
{ inst.on_transit() };
}) {
event.on_transit();
}
// enter to new // enter to new
if constexpr (requires(to_state_t inst) { if constexpr (requires(to_state_t inst) {
{ inst.enter(std::declval<EvT>()) }; { inst.enter(std::declval<EvT>()) };
}) { }) {
std::get<curr_state_t>(states).enter(event); std::get<curr_state_t>(*states).enter(event);
} else if constexpr (requires(to_state_t inst) { } else if constexpr (requires(to_state_t inst) {
{ inst.enter() }; { inst.enter() };
}) { }) {
std::get<curr_state_t>(states).enter(); std::get<curr_state_t>(*states).enter();
}
} }
}, },
*currentState); *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([](MccFiniteStateMachine* inst) {
//
_dispatchEventFunc<EvT>.erase(inst);
});
}); });
} }
MccFiniteStateMachine(const MccFiniteStateMachine& other) { copyInstance(&other, this); }
MccFiniteStateMachine(MccFiniteStateMachine&& other) { moveInstance(&other, this); }
MccFiniteStateMachine& operator=(const MccFiniteStateMachine& other) { return copyInstance(&other, this); }
MccFiniteStateMachine& operator=(MccFiniteStateMachine&& other) { return moveInstance(&other, this); }
virtual ~MccFiniteStateMachine()
{
for (auto& func : _destroyFunc) {
func();
}
}
template <traits::fsm_event_c EvT> template <traits::fsm_event_c EvT>
auto dispatchEvent(EvT& event) auto dispatchEvent(EvT& event)