Clear pending function states when reloading GDScript

This commit is contained in:
Haoyu Qiu 2021-12-28 15:29:21 +08:00
parent a75afd61a7
commit 53af7ee482
2 changed files with 14 additions and 8 deletions

View file

@ -77,6 +77,17 @@ Object *GDScriptNativeClass::instance() {
return ClassDB::instance(name); return ClassDB::instance(name);
} }
void GDScript::_clear_pending_func_states() {
GDScriptLanguage::get_singleton()->lock.lock();
while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
// Order matters since clearing the stack may already cause
// the GDSCriptFunctionState to be destroyed and thus removed from the list.
pending_func_states.remove(E);
E->self()->_clear_stack();
}
GDScriptLanguage::get_singleton()->lock.unlock();
}
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) { GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
/* STEP 1, CREATE */ /* STEP 1, CREATE */
@ -605,6 +616,7 @@ Error GDScript::reload(bool p_keep_state) {
for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
_set_subclass_path(E->get(), path); _set_subclass_path(E->get(), path);
} }
_clear_pending_func_states();
return OK; return OK;
} }
@ -931,14 +943,7 @@ void GDScript::_save_orphaned_subclasses() {
} }
GDScript::~GDScript() { GDScript::~GDScript() {
GDScriptLanguage::get_singleton()->lock.lock(); _clear_pending_func_states();
while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
// Order matters since clearing the stack may already cause
// the GDSCriptFunctionState to be destroyed and thus removed from the list.
pending_func_states.remove(E);
E->self()->_clear_stack();
}
GDScriptLanguage::get_singleton()->lock.unlock();
for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
memdelete(E->get()); memdelete(E->get());

View file

@ -112,6 +112,7 @@ class GDScript : public Script {
SelfList<GDScript> script_list; SelfList<GDScript> script_list;
SelfList<GDScriptFunctionState>::List pending_func_states; SelfList<GDScriptFunctionState>::List pending_func_states;
void _clear_pending_func_states();
GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error); GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error);