diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index d286f7971a..d229c70212 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -170,7 +170,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco /* STEP 2, INITIALIZE AND CONSTRUCT */ { MutexLock lock(GDScriptLanguage::singleton->mutex); - instances.insert(instance->owner); + instances.add(&instance->script_instance_list); } _super_implicit_constructor(this, instance, r_error); @@ -180,7 +180,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco instance->owner->set_script_instance(nullptr); { MutexLock lock(GDScriptLanguage::singleton->mutex); - instances.erase(p_owner); + instances.remove(&instance->script_instance_list); } ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text); } @@ -198,7 +198,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco instance->owner->set_script_instance(nullptr); { MutexLock lock(GDScriptLanguage::singleton->mutex); - instances.erase(p_owner); + instances.remove(&instance->script_instance_list); } ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text); } @@ -436,9 +436,12 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) } bool GDScript::instance_has(const Object *p_this) const { - MutexLock lock(GDScriptLanguage::singleton->mutex); + GDScriptInstance *instance = dynamic_cast(p_this->get_script_instance()); - return instances.has((Object *)p_this); + if (instance == nullptr) { + return false; + } + return instance->script.ptr() == this; } bool GDScript::has_source_code() const { @@ -750,7 +753,7 @@ Error GDScript::reload(bool p_keep_state) { { MutexLock lock(GDScriptLanguage::singleton->mutex); - has_instances = instances.size(); + has_instances = instances.first() != nullptr; } // Check condition but reset flag before early return @@ -2045,8 +2048,8 @@ GDScriptInstance::~GDScriptInstance() { } } - if (script.is_valid() && owner) { - script->instances.erase(owner); + if (script.is_valid()) { + script->instances.remove(&script_instance_list); } } @@ -2472,15 +2475,13 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload //save state and remove script from instances HashMap>> &map = to_reload[scr]; - while (scr->instances.front()) { - Object *obj = scr->instances.front()->get(); + while (scr->instances.first()) { + GDScriptInstance *instance = scr->instances.first()->self(); //save instance info List> state; - if (obj->get_script_instance()) { - obj->get_script_instance()->get_property_state(state); - map[obj->get_instance_id()] = state; - obj->set_script(Variant()); - } + instance->get_property_state(state); + map[instance->get_owner()->get_instance_id()] = state; + instance->get_owner()->set_script(Variant()); } //same thing for placeholders diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index ed6eabd675..a50cce6eec 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -172,7 +172,7 @@ private: Error _static_init(); void _static_default_init(); // Initialize static variables with default values based on their types. - RBSet instances; + SelfList::List instances; bool destructing = false; bool clearing = false; //exported members @@ -364,6 +364,9 @@ class GDScriptInstance : public ScriptInstance { SelfList::List pending_func_states; + // Replacing `SelfList` with a better implementation could save 16bytes from the self and list pointer. + SelfList script_instance_list; // Linked list of instances with the same script. + void _call_implicit_ready_recursively(GDScript *p_script); public: @@ -400,7 +403,7 @@ public: virtual const Variant get_rpc_config() const; - GDScriptInstance() {} + GDScriptInstance() : script_instance_list(this) {} ~GDScriptInstance(); }; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 46fcff16cc..f3e7cc8d02 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -3075,45 +3075,8 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser: //validate instances if keeping state if (p_keep_state) { - for (RBSet::Element *E = p_script->instances.front(); E;) { - RBSet::Element *N = E->next(); - - ScriptInstance *si = E->get()->get_script_instance(); - if (si->is_placeholder()) { -#ifdef TOOLS_ENABLED - PlaceHolderScriptInstance *psi = static_cast(si); - - if (p_script->is_tool()) { - //re-create as an instance - p_script->placeholders.erase(psi); //remove placeholder - - GDScriptInstance *instance = memnew(GDScriptInstance); - instance->members.resize(p_script->member_indices.size()); - instance->script = Ref(p_script); - instance->owner = E->get(); - - //needed for hot reloading - for (const KeyValue &F : p_script->member_indices) { - instance->member_indices_cache[F.key] = F.value.index; - } - instance->owner->set_script_instance(instance); - - /* STEP 2, INITIALIZE AND CONSTRUCT */ - - Callable::CallError ce; - p_script->initializer->call(instance, nullptr, 0, ce); - - if (ce.error != Callable::CallError::CALL_OK) { - //well, tough luck, not gonna do anything here - } - } -#endif // TOOLS_ENABLED - } else { - GDScriptInstance *gi = static_cast(si); - gi->reload_members(); - } - - E = N; + for (SelfList *E = p_script->instances.first(); E; E = E->next()) { + E->self()->reload_members(); } } #endif //DEBUG_ENABLED