Skip to content

Commit 2a1ccc0

Browse files
committed
Merge pull request #118186 from HolonProduction/gdscript/instances-self-list
GDScript: Use linked list for instance tracking.
2 parents 4286c20 + 3d8ab75 commit 2a1ccc0

3 files changed

Lines changed: 23 additions & 56 deletions

File tree

modules/gdscript/gdscript.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
170170
/* STEP 2, INITIALIZE AND CONSTRUCT */
171171
{
172172
MutexLock lock(GDScriptLanguage::singleton->mutex);
173-
instances.insert(instance->owner);
173+
instances.add(&instance->script_instance_list);
174174
}
175175

176176
_super_implicit_constructor(this, instance, r_error);
@@ -180,7 +180,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
180180
instance->owner->set_script_instance(nullptr);
181181
{
182182
MutexLock lock(GDScriptLanguage::singleton->mutex);
183-
instances.erase(p_owner);
183+
instances.remove(&instance->script_instance_list);
184184
}
185185
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text);
186186
}
@@ -198,7 +198,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
198198
instance->owner->set_script_instance(nullptr);
199199
{
200200
MutexLock lock(GDScriptLanguage::singleton->mutex);
201-
instances.erase(p_owner);
201+
instances.remove(&instance->script_instance_list);
202202
}
203203
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text);
204204
}
@@ -436,9 +436,12 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
436436
}
437437

438438
bool GDScript::instance_has(const Object *p_this) const {
439-
MutexLock lock(GDScriptLanguage::singleton->mutex);
439+
GDScriptInstance *instance = dynamic_cast<GDScriptInstance *>(p_this->get_script_instance());
440440

441-
return instances.has((Object *)p_this);
441+
if (instance == nullptr) {
442+
return false;
443+
}
444+
return instance->script.ptr() == this;
442445
}
443446

444447
bool GDScript::has_source_code() const {
@@ -750,7 +753,7 @@ Error GDScript::reload(bool p_keep_state) {
750753
{
751754
MutexLock lock(GDScriptLanguage::singleton->mutex);
752755

753-
has_instances = instances.size();
756+
has_instances = instances.first() != nullptr;
754757
}
755758

756759
// Check condition but reset flag before early return
@@ -2045,8 +2048,8 @@ GDScriptInstance::~GDScriptInstance() {
20452048
}
20462049
}
20472050

2048-
if (script.is_valid() && owner) {
2049-
script->instances.erase(owner);
2051+
if (script.is_valid()) {
2052+
script->instances.remove(&script_instance_list);
20502053
}
20512054
}
20522055

@@ -2472,15 +2475,13 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload
24722475
//save state and remove script from instances
24732476
HashMap<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[scr];
24742477

2475-
while (scr->instances.front()) {
2476-
Object *obj = scr->instances.front()->get();
2478+
while (scr->instances.first()) {
2479+
GDScriptInstance *instance = scr->instances.first()->self();
24772480
//save instance info
24782481
List<Pair<StringName, Variant>> state;
2479-
if (obj->get_script_instance()) {
2480-
obj->get_script_instance()->get_property_state(state);
2481-
map[obj->get_instance_id()] = state;
2482-
obj->set_script(Variant());
2483-
}
2482+
instance->get_property_state(state);
2483+
map[instance->get_owner()->get_instance_id()] = state;
2484+
instance->get_owner()->set_script(Variant());
24842485
}
24852486

24862487
//same thing for placeholders

modules/gdscript/gdscript.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class GDScript : public Script {
172172
Error _static_init();
173173
void _static_default_init(); // Initialize static variables with default values based on their types.
174174

175-
RBSet<Object *> instances;
175+
SelfList<GDScriptInstance>::List instances;
176176
bool destructing = false;
177177
bool clearing = false;
178178
//exported members
@@ -364,6 +364,9 @@ class GDScriptInstance : public ScriptInstance {
364364

365365
SelfList<GDScriptFunctionState>::List pending_func_states;
366366

367+
// Replacing `SelfList` with a better implementation could save 16bytes from the self and list pointer.
368+
SelfList<GDScriptInstance> script_instance_list; // Linked list of instances with the same script.
369+
367370
void _call_implicit_ready_recursively(GDScript *p_script);
368371

369372
public:
@@ -400,7 +403,7 @@ class GDScriptInstance : public ScriptInstance {
400403

401404
virtual const Variant get_rpc_config() const;
402405

403-
GDScriptInstance() {}
406+
GDScriptInstance() : script_instance_list(this) {}
404407
~GDScriptInstance();
405408
};
406409

modules/gdscript/gdscript_compiler.cpp

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,45 +3075,8 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser:
30753075
//validate instances if keeping state
30763076

30773077
if (p_keep_state) {
3078-
for (RBSet<Object *>::Element *E = p_script->instances.front(); E;) {
3079-
RBSet<Object *>::Element *N = E->next();
3080-
3081-
ScriptInstance *si = E->get()->get_script_instance();
3082-
if (si->is_placeholder()) {
3083-
#ifdef TOOLS_ENABLED
3084-
PlaceHolderScriptInstance *psi = static_cast<PlaceHolderScriptInstance *>(si);
3085-
3086-
if (p_script->is_tool()) {
3087-
//re-create as an instance
3088-
p_script->placeholders.erase(psi); //remove placeholder
3089-
3090-
GDScriptInstance *instance = memnew(GDScriptInstance);
3091-
instance->members.resize(p_script->member_indices.size());
3092-
instance->script = Ref<GDScript>(p_script);
3093-
instance->owner = E->get();
3094-
3095-
//needed for hot reloading
3096-
for (const KeyValue<StringName, GDScript::MemberInfo> &F : p_script->member_indices) {
3097-
instance->member_indices_cache[F.key] = F.value.index;
3098-
}
3099-
instance->owner->set_script_instance(instance);
3100-
3101-
/* STEP 2, INITIALIZE AND CONSTRUCT */
3102-
3103-
Callable::CallError ce;
3104-
p_script->initializer->call(instance, nullptr, 0, ce);
3105-
3106-
if (ce.error != Callable::CallError::CALL_OK) {
3107-
//well, tough luck, not gonna do anything here
3108-
}
3109-
}
3110-
#endif // TOOLS_ENABLED
3111-
} else {
3112-
GDScriptInstance *gi = static_cast<GDScriptInstance *>(si);
3113-
gi->reload_members();
3114-
}
3115-
3116-
E = N;
3078+
for (SelfList<GDScriptInstance> *E = p_script->instances.first(); E; E = E->next()) {
3079+
E->self()->reload_members();
31173080
}
31183081
}
31193082
#endif //DEBUG_ENABLED

0 commit comments

Comments
 (0)