...
This commit is contained in:
parent
e069ed84f0
commit
9bee1ca0ea
@ -238,6 +238,40 @@ protected:
|
||||
template <traits::fsm_event_c EvT>
|
||||
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:
|
||||
template <traits::fsm_state_c 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 {
|
||||
_dispatchEventFunc<EvT>[this] = [states, currentState, this](EvT& event) mutable {
|
||||
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>;
|
||||
if constexpr (std::is_void_v<to_state_t>) {
|
||||
/// throw?!!
|
||||
return;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
// 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.on_transit() };
|
||||
}) {
|
||||
event.on_transit();
|
||||
}
|
||||
|
||||
// transit ...
|
||||
if constexpr (requires(EvT inst) {
|
||||
{ inst.on_transit() };
|
||||
}) {
|
||||
event.on_transit();
|
||||
}
|
||||
*currentState = std::get<to_state_t*>(*states);
|
||||
|
||||
// enter to new
|
||||
if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter(std::declval<EvT>()) };
|
||||
}) {
|
||||
std::get<curr_state_t>(states).enter(event);
|
||||
} else if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter() };
|
||||
}) {
|
||||
std::get<curr_state_t>(states).enter();
|
||||
// enter to new
|
||||
if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter(std::declval<EvT>()) };
|
||||
}) {
|
||||
std::get<curr_state_t>(*states).enter(event);
|
||||
} else if constexpr (requires(to_state_t inst) {
|
||||
{ inst.enter() };
|
||||
}) {
|
||||
std::get<curr_state_t>(*states).enter();
|
||||
}
|
||||
}
|
||||
},
|
||||
*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>
|
||||
auto dispatchEvent(EvT& event)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user