...
This commit is contained in:
parent
e069ed84f0
commit
9bee1ca0ea
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user