From aca5cfc91346371a60e42476af52a3a9fa6afde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 8 Jan 2025 13:43:17 +0100 Subject: [PATCH 1/3] Rationalize parsing of file system cache --- editor/editor_file_system.cpp | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index b8ce3ff65bf..cd9c5048f3b 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -383,33 +383,23 @@ void EditorFileSystem::_scan_filesystem() { name = cpath.path_join(name); FileCache fc; - fc.type = split[1]; - if (fc.type.contains_char('/')) { - fc.type = split[1].get_slice("/", 0); - fc.resource_script_class = split[1].get_slice("/", 1); - } + fc.type = split[1].get_slice("/", 0); + fc.resource_script_class = split[1].get_slice("/", 1); fc.uid = split[2].to_int(); fc.modification_time = split[3].to_int(); fc.import_modification_time = split[4].to_int(); fc.import_valid = split[5].to_int() != 0; fc.import_group_file = split[6].strip_edges(); - fc.script_class_name = split[7].get_slice("<>", 0); - fc.script_class_extends = split[7].get_slice("<>", 1); - fc.script_class_icon_path = split[7].get_slice("<>", 2); - fc.import_md5 = split[7].get_slice("<>", 3); - String dest_paths = split[7].get_slice("<>", 4); - if (!dest_paths.is_empty()) { - fc.import_dest_paths = dest_paths.split("<*>"); - } - - String deps = split[8].strip_edges(); - if (deps.length()) { - Vector dp = deps.split("<>"); - for (int i = 0; i < dp.size(); i++) { - const String &path = dp[i]; - fc.deps.push_back(path); - } + { + const Vector &slices = split[7].split("<>"); + ERR_CONTINUE(slices.size() < 5); + fc.script_class_name = slices[0]; + fc.script_class_extends = slices[1]; + fc.script_class_icon_path = slices[2]; + fc.import_md5 = slices[3]; + fc.import_dest_paths = slices[4].split("<*>"); } + fc.deps = split[8].strip_edges().split("<>"); file_cache[name] = fc; } From 318af42020cd349c5c9c3e4c88aa87249ca224b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 8 Jan 2025 13:21:47 +0100 Subject: [PATCH 2/3] Include more attributes in the global class names cache --- core/config/project_settings.cpp | 4 +- core/object/script_language.cpp | 33 +++- core/object/script_language.h | 8 +- core/object/script_language_extension.h | 8 +- editor/create_dialog.cpp | 10 +- editor/editor_file_system.cpp | 152 ++++++++---------- editor/editor_file_system.h | 50 +++--- modules/gdscript/gdscript.cpp | 8 +- modules/gdscript/gdscript.h | 2 +- .../gdscript/tests/gdscript_test_runner.cpp | 6 +- modules/gdscript/tests/test_gdscript.cpp | 4 +- modules/mono/csharp_script.cpp | 4 +- modules/mono/csharp_script.h | 2 +- .../Core/Bridge/ManagedCallbacks.cs | 2 +- .../Core/Bridge/ScriptManagerBridge.cs | 12 +- modules/mono/mono_gd/gd_mono_cache.h | 2 +- 16 files changed, 174 insertions(+), 133 deletions(-) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index fdcd4f9b606..a12b8968311 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1263,10 +1263,10 @@ void ProjectSettings::refresh_global_class_list() { Array script_classes = get_global_class_list(); for (int i = 0; i < script_classes.size(); i++) { Dictionary c = script_classes[i]; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"]); + ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } } diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 4ef53dba1df..33bf7ab48a0 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -269,10 +269,10 @@ void ScriptServer::init_languages() { for (const Variant &script_class : script_classes) { Dictionary c = script_class; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - add_global_class(c["class"], c["base"], c["language"], c["path"]); + add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } ProjectSettings::get_singleton()->clear("_global_script_classes"); } @@ -281,10 +281,10 @@ void ScriptServer::init_languages() { Array script_classes = ProjectSettings::get_singleton()->get_global_class_list(); for (const Variant &script_class : script_classes) { Dictionary c = script_class; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - add_global_class(c["class"], c["base"], c["language"], c["path"]); + add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } } @@ -390,7 +390,7 @@ void ScriptServer::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) { +void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path, bool p_is_abstract, bool p_is_tool) { ERR_FAIL_COND_MSG(p_class == p_base || (global_classes.has(p_base) && get_global_class_native_base(p_base) == p_class), "Cyclic inheritance in script class."); GlobalScriptClass *existing = global_classes.getptr(p_class); if (existing) { @@ -399,6 +399,8 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName existing->base = p_base; existing->path = p_path; existing->language = p_language; + existing->is_abstract = p_is_abstract; + existing->is_tool = p_is_tool; inheriters_cache_dirty = true; } } else { @@ -407,6 +409,8 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName g.language = p_language; g.path = p_path; g.base = p_base; + g.is_abstract = p_is_abstract; + g.is_tool = p_is_tool; global_classes[p_class] = g; inheriters_cache_dirty = true; } @@ -480,6 +484,16 @@ StringName ScriptServer::get_global_class_native_base(const String &p_class) { return base; } +bool ScriptServer::is_global_class_abstract(const String &p_class) { + ERR_FAIL_COND_V(!global_classes.has(p_class), false); + return global_classes[p_class].is_abstract; +} + +bool ScriptServer::is_global_class_tool(const String &p_class) { + ERR_FAIL_COND_V(!global_classes.has(p_class), false); + return global_classes[p_class].is_tool; +} + void ScriptServer::get_global_class_list(List *r_global_classes) { List classes; for (const KeyValue &E : global_classes) { @@ -507,12 +521,15 @@ void ScriptServer::save_global_classes() { get_global_class_list(&gc); Array gcarr; for (const StringName &E : gc) { + const GlobalScriptClass &global_class = global_classes[E]; Dictionary d; d["class"] = E; - d["language"] = global_classes[E].language; - d["path"] = global_classes[E].path; - d["base"] = global_classes[E].base; + d["language"] = global_class.language; + d["path"] = global_class.path; + d["base"] = global_class.base; d["icon"] = class_icons.get(E, ""); + d["is_abstract"] = global_class.is_abstract; + d["is_tool"] = global_class.is_tool; gcarr.push_back(d); } ProjectSettings::get_singleton()->store_global_class_list(gcarr); diff --git a/core/object/script_language.h b/core/object/script_language.h index 6ceeb428751..8158d633ae1 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -62,6 +62,8 @@ class ScriptServer { StringName language; String path; StringName base; + bool is_abstract = false; + bool is_tool = false; }; static HashMap global_classes; @@ -86,7 +88,7 @@ class ScriptServer { static void thread_exit(); static void global_classes_clear(); - static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path); + static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path, bool p_is_abstract, bool p_is_tool); static void remove_global_class(const StringName &p_class); static void remove_global_class_by_path(const String &p_path); static bool is_global_class(const StringName &p_class); @@ -94,6 +96,8 @@ class ScriptServer { static String get_global_class_path(const String &p_class); static StringName get_global_class_base(const String &p_class); static StringName get_global_class_native_base(const String &p_class); + static bool is_global_class_abstract(const String &p_class); + static bool is_global_class_tool(const String &p_class); static void get_global_class_list(List *r_global_classes); static void get_inheriters_list(const StringName &p_base_type, List *r_classes); static void save_global_classes(); @@ -443,7 +447,7 @@ class ScriptLanguage : public Object { virtual void frame(); virtual bool handles_global_class_type(const String &p_type) const { return false; } - virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const { return String(); } + virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr, bool *r_is_abstract = nullptr, bool *r_is_tool = nullptr) const { return String(); } virtual ~ScriptLanguage() {} }; diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 09c395e71e8..715ec43fb35 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -672,7 +672,7 @@ class ScriptLanguageExtension : public ScriptLanguage { GDVIRTUAL1RC_REQUIRED(Dictionary, _get_global_class_name, const String &) - virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override { + virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr, bool *r_is_abstract = nullptr, bool *r_is_tool = nullptr) const override { Dictionary ret; GDVIRTUAL_CALL(_get_global_class_name, p_path, ret); if (!ret.has("name")) { @@ -684,6 +684,12 @@ class ScriptLanguageExtension : public ScriptLanguage { if (r_icon_path != nullptr && ret.has("icon_path")) { *r_icon_path = ret["icon_path"]; } + if (r_is_abstract != nullptr && ret.has("is_abstract")) { + *r_is_abstract = ret["is_abstract"]; + } + if (r_is_tool != nullptr && ret.has("is_tool")) { + *r_is_tool = ret["is_tool"]; + } return ret["name"]; } }; diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 7f1670bcb64..f0b2ed6e469 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -315,18 +315,14 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const StringN r_item->set_metadata(0, p_type); r_item->set_text(0, p_type); - String script_path = ScriptServer::get_global_class_path(p_type); - Ref