@@ -984,20 +984,6 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
984
984
return true ;
985
985
}
986
986
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
-
1001
987
Variant EditorData::script_class_instance (const String &p_class) {
1002
988
if (ScriptServer::is_global_class (p_class)) {
1003
989
Ref<Script> script = script_class_load_script (p_class);
@@ -1026,22 +1012,25 @@ void EditorData::script_class_set_icon_path(const String &p_class, const String
1026
1012
_script_class_icon_paths[p_class] = p_icon_path;
1027
1013
}
1028
1014
1029
- String EditorData::script_class_get_icon_path (const String &p_class) const {
1030
- if (!ScriptServer::is_global_class (p_class)) {
1031
- return String ();
1032
- }
1033
-
1015
+ String EditorData::script_class_get_icon_path (const String &p_class, bool *r_valid) const {
1034
1016
String current = p_class;
1035
- String ret = _script_class_icon_paths[current];
1036
- while (ret.is_empty ()) {
1037
- current = script_class_get_base (current);
1017
+ while (true ) {
1038
1018
if (!ScriptServer::is_global_class (current)) {
1019
+ // If the classnames chain has a native class ancestor, we're done with success.
1020
+ if (r_valid) {
1021
+ *r_valid = ClassDB::class_exists (current);
1022
+ }
1039
1023
return String ();
1040
1024
}
1041
- ret = _script_class_icon_paths.has (current) ? _script_class_icon_paths[current] : String ();
1025
+ HashMap<StringName, String>::ConstIterator E = _script_class_icon_paths.find (current);
1026
+ if ((bool )E) {
1027
+ if (r_valid) {
1028
+ *r_valid = true ;
1029
+ }
1030
+ return E->value ;
1031
+ }
1032
+ current = ScriptServer::get_global_class_base (current);
1042
1033
}
1043
-
1044
- return ret;
1045
1034
}
1046
1035
1047
1036
StringName EditorData::script_class_get_name (const String &p_path) const {
@@ -1126,58 +1115,67 @@ Ref<Texture2D> EditorData::_load_script_icon(const String &p_path) const {
1126
1115
return nullptr ;
1127
1116
}
1128
1117
1129
- Ref<Texture2D> EditorData::get_script_icon (const Ref<Script> &p_script ) {
1118
+ Ref<Texture2D> EditorData::get_script_icon (const String &p_script_path ) {
1130
1119
// Take from the local cache, if available.
1131
- if (_script_icon_cache.has (p_script )) {
1120
+ if (_script_icon_cache.has (p_script_path )) {
1132
1121
// Can be an empty value if we can't resolve any icon for this script.
1133
1122
// An empty value is still cached to avoid unnecessary attempts at resolving it again.
1134
- return _script_icon_cache[p_script];
1123
+ return _script_icon_cache[p_script_path];
1124
+ }
1125
+
1126
+ // Fast path in case the whole hierarchy is made of global classes.
1127
+ StringName class_name = script_class_get_name (p_script_path);
1128
+ {
1129
+ if (class_name != StringName ()) {
1130
+ bool icon_valid = false ;
1131
+ String icon_path = script_class_get_icon_path (class_name, &icon_valid);
1132
+ if (icon_valid) {
1133
+ Ref<Texture2D> icon = _load_script_icon (icon_path);
1134
+ _script_icon_cache[p_script_path] = icon;
1135
+ return icon;
1136
+ }
1137
+ }
1135
1138
}
1136
1139
1137
- Ref<Script> base_scr = p_script ;
1140
+ Ref<Script> base_scr = ResourceLoader::load (p_script_path, " Script " ) ;
1138
1141
while (base_scr.is_valid ()) {
1139
1142
// Check for scripted classes.
1140
1143
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 ()) {
1144
+ StringName base_class_name = script_class_get_name (base_scr->get_path ());
1145
+ if (base_scr->is_built_in () || base_class_name == StringName ()) {
1143
1146
icon_path = base_scr->get_class_icon_path ();
1144
1147
} else {
1145
- icon_path = script_class_get_icon_path (class_name );
1148
+ icon_path = script_class_get_icon_path (base_class_name );
1146
1149
}
1147
1150
1148
1151
Ref<Texture2D> icon = _load_script_icon (icon_path);
1149
1152
if (icon.is_valid ()) {
1150
- _script_icon_cache[p_script ] = icon;
1153
+ _script_icon_cache[p_script_path ] = icon;
1151
1154
return icon;
1152
1155
}
1153
1156
1154
1157
// Check for legacy custom classes defined by plugins.
1155
1158
// TODO: Should probably be deprecated in 4.x
1156
1159
const EditorData::CustomType *ctype = get_custom_type_by_path (base_scr->get_path ());
1157
1160
if (ctype && ctype->icon .is_valid ()) {
1158
- _script_icon_cache[p_script ] = ctype->icon ;
1161
+ _script_icon_cache[p_script_path ] = ctype->icon ;
1159
1162
return ctype->icon ;
1160
1163
}
1161
1164
1162
1165
// Move to the base class.
1163
1166
base_scr = base_scr->get_base_script ();
1164
1167
}
1165
1168
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
1169
// Check if the base type is an extension-defined type.
1172
- Ref<Texture2D> ext_icon = extension_class_get_icon (base_type );
1170
+ Ref<Texture2D> ext_icon = extension_class_get_icon (class_name );
1173
1171
if (ext_icon.is_valid ()) {
1174
- _script_icon_cache[p_script ] = ext_icon;
1172
+ _script_icon_cache[p_script_path ] = ext_icon;
1175
1173
return ext_icon;
1176
1174
}
1177
1175
1178
1176
// If no icon found, cache it as null.
1179
- _script_icon_cache[p_script ] = Ref<Texture >();
1180
- return nullptr ;
1177
+ _script_icon_cache[p_script_path ] = Ref<Texture2D >();
1178
+ return Ref<Texture2D>() ;
1181
1179
}
1182
1180
1183
1181
void EditorData::clear_script_icon_cache () {
0 commit comments