Compare commits

...

4 Commits

Author SHA1 Message Date
monxa 8ac2219d32
Merge 20be87904a into 60a767032e 2024-09-29 19:47:54 +00:00
Alexander Montag 20be87904a
Focus tree when search panel is closed 2024-09-29 21:47:38 +02:00
Serhii Snitsaruk 60a767032e
Merge pull request #226 from limbonaut/fix-hsm-exit-crash
Fix invalid access errors on exit in LimboHSM
2024-09-26 16:54:31 +02:00
Serhii Snitsaruk 60142b191d
Fix invalid access crash on exit in LimboHSM
Since #131, `LimboState::_exit()` became a source of potential crashes
if object references are used without a validity check. It's too easy
to miss this, which can lead to game crashing during runtime.

This fix reverts #131 change and proposes alternative approach of
re-activating root HSM upon tree entering if it was previously active.
Note that it's not an ideal solution, as some state will be lost upon
re-parenting: HSM exits and then re-activates and enters its initial state.
2024-09-22 13:57:15 +02:00
5 changed files with 25 additions and 5 deletions

View File

@ -383,6 +383,12 @@ void TreeSearch::_select_next_match() {
_select_first_match();
}
void TreeSearch::_on_search_panel_visibility_changed() {
if (tree_reference && !search_panel->is_visible()) {
tree_reference->grab_focus();
}
}
template <typename T>
inline bool TreeSearch::_vector_has_bsearch(Vector<T *> &p_vec, T *element) const {
int idx = p_vec.bsearch(element, true);
@ -439,6 +445,7 @@ void TreeSearch::update_search(Tree *p_tree) {
TreeSearch::TreeSearch(TreeSearchPanel *p_search_panel) {
search_panel = p_search_panel;
search_panel->connect("text_submitted", callable_mp(this, &TreeSearch::_select_next_match));
search_panel->connect("visibility_changed", callable_mp(this, &TreeSearch::_on_search_panel_visibility_changed));
}
/* !TreeSearch */

View File

@ -90,6 +90,8 @@ private:
void _select_first_match();
void _select_next_match();
void _on_search_panel_visibility_changed();
// TODO: make p_vec ref `const` once Vector::bsearch is const. See: https://github.com/godotengine/godot/pull/90341
template <typename T>
bool _vector_has_bsearch(Vector<T *> &p_vec, T *element) const;

View File

@ -263,6 +263,21 @@ void LimboHSM::_validate_property(PropertyInfo &p_property) const {
void LimboHSM::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_POST_ENTER_TREE: {
if (was_active && is_root()) {
// Re-activate the root HSM if it was previously active.
// Typically, this happens when the node is re-entered scene repeatedly (e.g., re-parenting, pooling).
set_active(true);
}
} break;
case NOTIFICATION_EXIT_TREE: {
if (is_root()) {
// Remember active status for re-parenting and exit state machine
// to release resources and signal connections if active.
was_active = active;
if (is_active()) {
_exit();
}
}
} break;
case NOTIFICATION_PROCESS: {
_update(get_process_delta_time());

View File

@ -55,6 +55,7 @@ private:
LimboState *previous_active;
LimboState *next_active;
bool updating = false;
bool was_active = false;
HashMap<TransitionKey, Transition, TransitionKeyHasher> transitions;

View File

@ -190,11 +190,6 @@ void LimboState::_notification(int p_what) {
_update_blackboard_plan();
}
} break;
case NOTIFICATION_PREDELETE: {
if (is_active()) {
_exit();
}
} break;
}
}