From c4df916bdf43af9ced81f8bb3de83484d50d89a9 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sat, 20 Apr 2024 21:30:26 +0200 Subject: [PATCH] HSM: Delay state transition till update is finished --- bt/bt_state.cpp | 7 +++++-- hsm/limbo_hsm.cpp | 14 +++++++++++++- hsm/limbo_hsm.h | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/bt/bt_state.cpp b/bt/bt_state.cpp index b603cfa..c03c67c 100644 --- a/bt/bt_state.cpp +++ b/bt/bt_state.cpp @@ -63,9 +63,12 @@ void BTState::_setup() { } void BTState::_exit() { + if (tree_instance.is_valid()) { + tree_instance->abort(); + } else { + ERR_PRINT_ONCE("BTState: BehaviorTree is not assigned."); + } LimboState::_exit(); - ERR_FAIL_NULL(tree_instance); - tree_instance->abort(); } void BTState::_update(double p_delta) { diff --git a/hsm/limbo_hsm.cpp b/hsm/limbo_hsm.cpp index e97bd56..71c81aa 100644 --- a/hsm/limbo_hsm.cpp +++ b/hsm/limbo_hsm.cpp @@ -88,7 +88,13 @@ void LimboHSM::_update(double p_delta) { } void LimboHSM::update(double p_delta) { + updating = true; _update(p_delta); + updating = false; + if (next_active) { + _change_state(next_active); + next_active = nullptr; + } } void LimboHSM::add_transition(LimboState *p_from_state, LimboState *p_to_state, const StringName &p_event) { @@ -170,7 +176,12 @@ bool LimboHSM::_dispatch(const StringName &p_event, const Variant &p_cargo) { } } if (permitted) { - _change_state(to_state); + if (!updating) { + _change_state(to_state); + } else if (!next_active) { + // Only set next_active if we are not already in the process of changing states. + next_active = to_state; + } event_consumed = true; } } @@ -263,5 +274,6 @@ LimboHSM::LimboHSM() { update_mode = UpdateMode::PHYSICS; active_state = nullptr; previous_active = nullptr; + next_active = nullptr; initial_state = nullptr; } diff --git a/hsm/limbo_hsm.h b/hsm/limbo_hsm.h index d8e5647..632498e 100644 --- a/hsm/limbo_hsm.h +++ b/hsm/limbo_hsm.h @@ -29,7 +29,9 @@ private: LimboState *initial_state; LimboState *active_state; LimboState *previous_active; + LimboState *next_active; HashMap transitions; + bool updating = false; _FORCE_INLINE_ uint64_t _get_transition_key(LimboState *p_from_state, const StringName &p_event) { uint64_t key = hash_djb2_one_64(Variant::OBJECT);