Skip to content

Commit c9acc56

Browse files
committed
Optimize enumeration of global classes in create dialog and autocomplete
1 parent 9b43474 commit c9acc56

8 files changed

+45
-99
lines changed

editor/connections_dialog.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ void ConnectionsDock::update_tree() {
14351435
doc_class_name = String();
14361436
}
14371437

1438-
class_icon = editor_data.get_script_icon(script_base);
1438+
class_icon = editor_data.get_script_icon(script_base->get_path());
14391439
if (class_icon.is_null() && has_theme_icon(native_base, EditorStringName(EditorIcons))) {
14401440
class_icon = get_editor_theme_icon(native_base);
14411441
}

editor/create_dialog.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,9 @@ void CreateDialog::_add_type(const StringName &p_type, TypeCategory p_type_categ
231231
inherits = ClassDB::get_parent_class(p_type);
232232
inherited_type = TypeCategory::CPP_TYPE;
233233
} else {
234-
if (p_type_category == TypeCategory::PATH_TYPE || ScriptServer::is_global_class(p_type)) {
235-
Ref<Script> scr;
236-
if (p_type_category == TypeCategory::PATH_TYPE) {
237-
ERR_FAIL_COND(!ResourceLoader::exists(p_type, "Script"));
238-
scr = ResourceLoader::load(p_type, "Script");
239-
} else {
240-
scr = EditorNode::get_editor_data().script_class_load_script(p_type);
241-
}
234+
if (p_type_category == TypeCategory::PATH_TYPE) {
235+
ERR_FAIL_COND(!ResourceLoader::exists(p_type, "Script"));
236+
Ref<Script> scr = ResourceLoader::load(p_type, "Script");
242237
ERR_FAIL_COND(scr.is_null());
243238

244239
Ref<Script> base = scr->get_base_script();
@@ -260,6 +255,10 @@ void CreateDialog::_add_type(const StringName &p_type, TypeCategory p_type_categ
260255
inherited_type = TypeCategory::PATH_TYPE;
261256
}
262257
}
258+
} else if (ScriptServer::is_global_class(p_type)) {
259+
inherits = ScriptServer::get_global_class_base(p_type);
260+
bool is_native_class = ClassDB::class_exists(inherits);
261+
inherited_type = is_native_class ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE;
263262
} else {
264263
inherits = custom_type_parents[p_type];
265264
if (ClassDB::class_exists(inherits)) {

editor/editor_data.cpp

+12-69
Original file line numberDiff line numberDiff line change
@@ -984,20 +984,6 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
984984
return true;
985985
}
986986

987-
StringName EditorData::script_class_get_base(const String &p_class) const {
988-
Ref<Script> script = script_class_load_script(p_class);
989-
if (script.is_null()) {
990-
return StringName();
991-
}
992-
993-
Ref<Script> base_script = script->get_base_script();
994-
if (base_script.is_null()) {
995-
return ScriptServer::get_global_class_base(p_class);
996-
}
997-
998-
return script->get_language()->get_global_class_name(base_script->get_path());
999-
}
1000-
1001987
Variant EditorData::script_class_instance(const String &p_class) {
1002988
if (ScriptServer::is_global_class(p_class)) {
1003989
Ref<Script> script = script_class_load_script(p_class);
@@ -1034,7 +1020,7 @@ String EditorData::script_class_get_icon_path(const String &p_class) const {
10341020
String current = p_class;
10351021
String ret = _script_class_icon_paths[current];
10361022
while (ret.is_empty()) {
1037-
current = script_class_get_base(current);
1023+
current = ScriptServer::get_global_class_base(current);
10381024
if (!ScriptServer::is_global_class(current)) {
10391025
return String();
10401026
}
@@ -1105,15 +1091,11 @@ void EditorData::script_class_load_icon_paths() {
11051091
}
11061092
}
11071093

1108-
Ref<Texture2D> EditorData::extension_class_get_icon(const String &p_class) const {
1094+
String EditorData::extension_class_get_icon_path(const String &p_class) const {
11091095
if (GDExtensionManager::get_singleton()->class_has_icon_path(p_class)) {
1110-
String icon_path = GDExtensionManager::get_singleton()->class_get_icon_path(p_class);
1111-
Ref<Texture2D> icon = _load_script_icon(icon_path);
1112-
if (icon.is_valid()) {
1113-
return icon;
1114-
}
1096+
return GDExtensionManager::get_singleton()->class_get_icon_path(p_class);
11151097
}
1116-
return nullptr;
1098+
return String();
11171099
}
11181100

11191101
Ref<Texture2D> EditorData::_load_script_icon(const String &p_path) const {
@@ -1126,58 +1108,19 @@ Ref<Texture2D> EditorData::_load_script_icon(const String &p_path) const {
11261108
return nullptr;
11271109
}
11281110

1129-
Ref<Texture2D> EditorData::get_script_icon(const Ref<Script> &p_script) {
1111+
Ref<Texture2D> EditorData::get_script_icon(const String &p_script_path) {
11301112
// Take from the local cache, if available.
1131-
if (_script_icon_cache.has(p_script)) {
1113+
if (_script_icon_cache.has(p_script_path)) {
11321114
// Can be an empty value if we can't resolve any icon for this script.
11331115
// An empty value is still cached to avoid unnecessary attempts at resolving it again.
1134-
return _script_icon_cache[p_script];
1116+
return _script_icon_cache[p_script_path];
11351117
}
11361118

1137-
Ref<Script> base_scr = p_script;
1138-
while (base_scr.is_valid()) {
1139-
// Check for scripted classes.
1140-
String icon_path;
1141-
StringName class_name = script_class_get_name(base_scr->get_path());
1142-
if (base_scr->is_built_in() || class_name == StringName()) {
1143-
icon_path = base_scr->get_class_icon_path();
1144-
} else {
1145-
icon_path = script_class_get_icon_path(class_name);
1146-
}
1147-
1148-
Ref<Texture2D> icon = _load_script_icon(icon_path);
1149-
if (icon.is_valid()) {
1150-
_script_icon_cache[p_script] = icon;
1151-
return icon;
1152-
}
1153-
1154-
// Check for legacy custom classes defined by plugins.
1155-
// TODO: Should probably be deprecated in 4.x
1156-
const EditorData::CustomType *ctype = get_custom_type_by_path(base_scr->get_path());
1157-
if (ctype && ctype->icon.is_valid()) {
1158-
_script_icon_cache[p_script] = ctype->icon;
1159-
return ctype->icon;
1160-
}
1161-
1162-
// Move to the base class.
1163-
base_scr = base_scr->get_base_script();
1164-
}
1165-
1166-
// No custom icon was found in the inheritance chain, so check the base
1167-
// class of the script instead.
1168-
String base_type;
1169-
p_script->get_language()->get_global_class_name(p_script->get_path(), &base_type);
1170-
1171-
// Check if the base type is an extension-defined type.
1172-
Ref<Texture2D> ext_icon = extension_class_get_icon(base_type);
1173-
if (ext_icon.is_valid()) {
1174-
_script_icon_cache[p_script] = ext_icon;
1175-
return ext_icon;
1176-
}
1177-
1178-
// If no icon found, cache it as null.
1179-
_script_icon_cache[p_script] = Ref<Texture>();
1180-
return nullptr;
1119+
StringName class_name = script_class_get_name(p_script_path);
1120+
String icon_path = script_class_get_icon_path(class_name);
1121+
Ref<Texture2D> icon = _load_script_icon(icon_path);
1122+
_script_icon_cache[p_script_path] = icon;
1123+
return icon;
11811124
}
11821125

11831126
void EditorData::clear_script_icon_cache() {

editor/editor_data.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class EditorData {
146146

147147
HashMap<StringName, String> _script_class_icon_paths;
148148
HashMap<String, StringName> _script_class_file_to_path;
149-
HashMap<Ref<Script>, Ref<Texture>> _script_icon_cache;
149+
HashMap<String, Ref<Texture>> _script_icon_cache;
150150

151151
Ref<Texture2D> _load_script_icon(const String &p_path) const;
152152

@@ -240,7 +240,6 @@ class EditorData {
240240
void notify_scene_saved(const String &p_path);
241241

242242
bool script_class_is_parent(const String &p_class, const String &p_inherits);
243-
StringName script_class_get_base(const String &p_class) const;
244243
Variant script_class_instance(const String &p_class);
245244

246245
Ref<Script> script_class_load_script(const String &p_class) const;
@@ -254,9 +253,9 @@ class EditorData {
254253
void script_class_save_icon_paths();
255254
void script_class_load_icon_paths();
256255

257-
Ref<Texture2D> extension_class_get_icon(const String &p_class) const;
256+
String extension_class_get_icon_path(const String &p_class) const;
258257

259-
Ref<Texture2D> get_script_icon(const Ref<Script> &p_script);
258+
Ref<Texture2D> get_script_icon(const String &p_script_path);
260259
void clear_script_icon_cache();
261260

262261
EditorData();

editor/editor_node.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -4823,22 +4823,21 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na
48234823
}
48244824
}
48254825

4826-
Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, const Ref<Script> &p_script, const String &p_fallback, bool p_fallback_script_to_theme) {
4826+
Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, const String &p_script_path, const String &p_fallback, bool p_fallback_script_to_theme) {
48274827
ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");
48284828
EditorData &ed = EditorNode::get_editor_data();
48294829

48304830
// Check for a script icon first.
4831-
if (p_script.is_valid()) {
4832-
Ref<Texture2D> script_icon = ed.get_script_icon(p_script);
4831+
if (!p_script_path.is_empty()) {
4832+
Ref<Texture2D> script_icon = ed.get_script_icon(p_script_path);
48334833
if (script_icon.is_valid()) {
48344834
return script_icon;
48354835
}
48364836

48374837
if (p_fallback_script_to_theme) {
48384838
// Look for the native base type in the editor theme. This is relevant for
48394839
// scripts extending other scripts and for built-in classes.
4840-
String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path());
4841-
String base_type = ScriptServer::get_global_class_native_base(script_class_name);
4840+
String base_type = ScriptServer::get_global_class_native_base(p_class);
48424841
if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) {
48434842
return theme->get_icon(base_type, EditorStringName(EditorIcons));
48444843
}
@@ -4849,9 +4848,14 @@ Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, cons
48494848
// directly.
48504849

48514850
// Check if the class name is an extension-defined type.
4852-
Ref<Texture2D> ext_icon = ed.extension_class_get_icon(p_class);
4853-
if (ext_icon.is_valid()) {
4854-
return ext_icon;
4851+
{
4852+
const String &icon_path = ed.extension_class_get_icon_path(p_class);
4853+
if (!icon_path.is_empty()) {
4854+
const Ref<Texture2D> &icon = ResourceLoader::load(icon_path);
4855+
if (icon.is_valid()) {
4856+
return icon;
4857+
}
4858+
}
48554859
}
48564860

48574861
// Check if the class name is a custom type.
@@ -4894,18 +4898,18 @@ Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String
48944898
scr = p_object;
48954899
}
48964900

4897-
return _get_class_or_script_icon(p_object->get_class(), scr, p_fallback);
4901+
return _get_class_or_script_icon(p_object->get_class(), scr.is_valid() ? scr->get_path() : String(), p_fallback);
48984902
}
48994903

49004904
Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) {
49014905
ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");
49024906

4903-
Ref<Script> scr;
4907+
String script_path;
49044908
if (ScriptServer::is_global_class(p_class)) {
4905-
scr = EditorNode::get_editor_data().script_class_load_script(p_class);
4909+
script_path = ScriptServer::get_global_class_path(p_class);
49064910
}
49074911

4908-
return _get_class_or_script_icon(p_class, scr, p_fallback, true);
4912+
return _get_class_or_script_icon(p_class, script_path, p_fallback, true);
49094913
}
49104914

49114915
bool EditorNode::is_object_of_custom_type(const Object *p_object, const StringName &p_class) {

editor/editor_node.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ class EditorNode : public Node {
675675
void _feature_profile_changed();
676676
bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class);
677677

678-
Ref<Texture2D> _get_class_or_script_icon(const String &p_class, const Ref<Script> &p_script, const String &p_fallback = "Object", bool p_fallback_script_to_theme = false);
678+
Ref<Texture2D> _get_class_or_script_icon(const String &p_class, const String &p_script_path, const String &p_fallback = "Object", bool p_fallback_script_to_theme = false);
679679

680680
void _pick_main_scene_custom_action(const String &p_custom_action_name);
681681

modules/gdscript/tests/gdscript_test_runner.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,16 @@ static bool generate_class_index_recursive(const String &p_dir) {
367367
}
368368
String base_type;
369369
String source_file = current_dir.path_join(next);
370-
String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(source_file, &base_type);
370+
bool is_abstract = false;
371+
String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(source_file, &base_type, nullptr, &is_abstract);
371372
if (class_name.is_empty()) {
372373
next = dir->get_next();
373374
continue;
374375
}
375376
ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false,
376377
"Class name '" + class_name + "' from " + source_file + " is already used in " + ScriptServer::get_global_class_path(class_name));
377378

378-
ScriptServer::add_global_class(class_name, base_type, gdscript_name, source_file);
379+
ScriptServer::add_global_class(class_name, base_type, gdscript_name, source_file, is_abstract);
379380
}
380381

381382
next = dir->get_next();

modules/gdscript/tests/test_gdscript.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ void test(TestType p_type) {
275275
TypedArray<Dictionary> script_classes = ProjectSettings::get_singleton()->get_global_class_list();
276276
for (int i = 0; i < script_classes.size(); i++) {
277277
Dictionary c = script_classes[i];
278-
if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) {
278+
if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract")) {
279279
continue;
280280
}
281-
ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"]);
281+
ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"]);
282282
}
283283

284284
Vector<uint8_t> buf;

0 commit comments

Comments
 (0)