diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-21 11:31:05 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-21 11:31:05 +0100 |
commit | c02572d3d05fc59f20252bc77c1b8b002540f156 (patch) | |
tree | 86fcfab7e187bb9c51d31a8ca4a08f8424a0b5a8 /core/object/script_language.cpp | |
parent | a3c8ba6cd59e8bc5e23a0741398567955c7f95e7 (diff) | |
parent | 3dcf3801611a85170aaa31c3bfffc57a12ed58c2 (diff) | |
download | redot-engine-c02572d3d05fc59f20252bc77c1b8b002540f156.tar.gz |
Merge pull request #71683 from reduz/fast-script-class-inheritance-check
Implement a quick script inheritance check
Diffstat (limited to 'core/object/script_language.cpp')
-rw-r--r-- | core/object/script_language.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 66ef418e42..df5486512d 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -245,9 +245,12 @@ void ScriptServer::thread_exit() { } HashMap<StringName, ScriptServer::GlobalScriptClass> ScriptServer::global_classes; +HashMap<StringName, Vector<StringName>> ScriptServer::inheriters_cache; +bool ScriptServer::inheriters_cache_dirty = true; void ScriptServer::global_classes_clear() { global_classes.clear(); + inheriters_cache.clear(); } void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) { @@ -257,16 +260,44 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName g.path = p_path; g.base = p_base; global_classes[p_class] = g; + inheriters_cache_dirty = true; } void ScriptServer::remove_global_class(const StringName &p_class) { global_classes.erase(p_class); + inheriters_cache_dirty = true; +} + +void ScriptServer::get_inheriters_list(const StringName &p_base_type, List<StringName> *r_classes) { + if (inheriters_cache_dirty) { + inheriters_cache.clear(); + for (const KeyValue<StringName, GlobalScriptClass> &K : global_classes) { + if (!inheriters_cache.has(K.value.base)) { + inheriters_cache[K.value.base] = Vector<StringName>(); + } + inheriters_cache[K.value.base].push_back(K.key); + } + for (KeyValue<StringName, Vector<StringName>> &K : inheriters_cache) { + K.value.sort_custom<StringName::AlphCompare>(); + } + inheriters_cache_dirty = false; + } + + if (!inheriters_cache.has(p_base_type)) { + return; + } + + const Vector<StringName> &v = inheriters_cache[p_base_type]; + for (int i = 0; i < v.size(); i++) { + r_classes->push_back(v[i]); + } } void ScriptServer::remove_global_class_by_path(const String &p_path) { for (const KeyValue<StringName, GlobalScriptClass> &kv : global_classes) { if (kv.value.path == p_path) { global_classes.erase(kv.key); + inheriters_cache_dirty = true; return; } } |