feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -33,14 +33,13 @@
|
|||
#include "core/config/project_settings.h"
|
||||
#include "core/extension/gdextension_manager.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/io/image_loader.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "editor/multi_node_edit.h"
|
||||
#include "editor/plugins/editor_context_menu_plugin.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/property_utils.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
void EditorSelectionHistory::cleanup_history() {
|
||||
|
|
@ -48,7 +47,7 @@ void EditorSelectionHistory::cleanup_history() {
|
|||
bool fail = false;
|
||||
|
||||
for (int j = 0; j < history[i].path.size(); j++) {
|
||||
if (!history[i].path[j].ref.is_null()) {
|
||||
if (history[i].path[j].ref.is_valid()) {
|
||||
// If the node is a MultiNodeEdit node, examine it and see if anything is missing from it.
|
||||
Ref<MultiNodeEdit> multi_node_edit = history[i].path[j].ref;
|
||||
if (multi_node_edit.is_valid()) {
|
||||
|
|
@ -278,7 +277,7 @@ Vector<EditorPlugin *> EditorData::get_handling_sub_editors(Object *p_object) {
|
|||
|
||||
EditorPlugin *EditorData::get_editor_by_name(const String &p_name) {
|
||||
for (int i = editor_plugins.size() - 1; i > -1; i--) {
|
||||
if (editor_plugins[i]->get_name() == p_name) {
|
||||
if (editor_plugins[i]->get_plugin_name() == p_name) {
|
||||
return editor_plugins[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -317,7 +316,7 @@ Dictionary EditorData::get_editor_plugin_states() const {
|
|||
if (state.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
metadata[editor_plugins[i]->get_name()] = state;
|
||||
metadata[editor_plugins[i]->get_plugin_name()] = state;
|
||||
}
|
||||
|
||||
return metadata;
|
||||
|
|
@ -345,7 +344,7 @@ void EditorData::set_editor_plugin_states(const Dictionary &p_states) {
|
|||
String name = E->get();
|
||||
int idx = -1;
|
||||
for (int i = 0; i < editor_plugins.size(); i++) {
|
||||
if (editor_plugins[i]->get_name() == name) {
|
||||
if (editor_plugins[i]->get_plugin_name() == name) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
|
|
@ -538,14 +537,18 @@ Variant EditorData::instantiate_custom_type(const String &p_type, const String &
|
|||
if (get_custom_types()[p_inherits][i].name == p_type) {
|
||||
Ref<Script> script = get_custom_types()[p_inherits][i].script;
|
||||
|
||||
Variant ob = ClassDB::instantiate(p_inherits);
|
||||
ERR_FAIL_COND_V(!ob, Variant());
|
||||
// Store in a variant to initialize the refcount if needed.
|
||||
Variant v = ClassDB::instantiate(p_inherits);
|
||||
ERR_FAIL_COND_V(!v, Variant());
|
||||
Object *ob = v;
|
||||
|
||||
Node *n = Object::cast_to<Node>(ob);
|
||||
if (n) {
|
||||
n->set_name(p_type);
|
||||
}
|
||||
((Object *)ob)->set_script(script);
|
||||
return ob;
|
||||
PropertyUtils::assign_custom_type_script(ob, script);
|
||||
ob->set_script(script);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -839,9 +842,9 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
|
|||
return Ref<Script>();
|
||||
}
|
||||
Ref<Script> s = edited_scene[p_idx].root->get_script();
|
||||
if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) {
|
||||
if (s.is_null() && edited_scene[p_idx].root->get_child_count()) {
|
||||
Node *n = edited_scene[p_idx].root->get_child(0);
|
||||
while (!s.is_valid() && n && n->get_scene_file_path().is_empty()) {
|
||||
while (s.is_null() && n && n->get_scene_file_path().is_empty()) {
|
||||
s = n->get_script();
|
||||
n = n->get_parent();
|
||||
}
|
||||
|
|
@ -984,30 +987,18 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
|
|||
return true;
|
||||
}
|
||||
|
||||
StringName EditorData::script_class_get_base(const String &p_class) const {
|
||||
Ref<Script> script = script_class_load_script(p_class);
|
||||
if (script.is_null()) {
|
||||
return StringName();
|
||||
}
|
||||
|
||||
Ref<Script> base_script = script->get_base_script();
|
||||
if (base_script.is_null()) {
|
||||
return ScriptServer::get_global_class_base(p_class);
|
||||
}
|
||||
|
||||
return script->get_language()->get_global_class_name(base_script->get_path());
|
||||
}
|
||||
|
||||
Variant EditorData::script_class_instance(const String &p_class) {
|
||||
if (ScriptServer::is_global_class(p_class)) {
|
||||
Ref<Script> script = script_class_load_script(p_class);
|
||||
if (script.is_valid()) {
|
||||
// Store in a variant to initialize the refcount if needed.
|
||||
Variant obj = ClassDB::instantiate(script->get_instance_base_type());
|
||||
if (obj) {
|
||||
obj.operator Object *()->set_script(script);
|
||||
Variant v = ClassDB::instantiate(script->get_instance_base_type());
|
||||
if (v) {
|
||||
Object *obj = v;
|
||||
PropertyUtils::assign_custom_type_script(obj, script);
|
||||
obj->set_script(script);
|
||||
}
|
||||
return obj;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return Variant();
|
||||
|
|
@ -1026,22 +1017,25 @@ void EditorData::script_class_set_icon_path(const String &p_class, const String
|
|||
_script_class_icon_paths[p_class] = p_icon_path;
|
||||
}
|
||||
|
||||
String EditorData::script_class_get_icon_path(const String &p_class) const {
|
||||
if (!ScriptServer::is_global_class(p_class)) {
|
||||
return String();
|
||||
}
|
||||
|
||||
String EditorData::script_class_get_icon_path(const String &p_class, bool *r_valid) const {
|
||||
String current = p_class;
|
||||
String ret = _script_class_icon_paths[current];
|
||||
while (ret.is_empty()) {
|
||||
current = script_class_get_base(current);
|
||||
while (true) {
|
||||
if (!ScriptServer::is_global_class(current)) {
|
||||
// If the classnames chain has a native class ancestor, we're done with success.
|
||||
if (r_valid) {
|
||||
*r_valid = ClassDB::class_exists(current);
|
||||
}
|
||||
return String();
|
||||
}
|
||||
ret = _script_class_icon_paths.has(current) ? _script_class_icon_paths[current] : String();
|
||||
HashMap<StringName, String>::ConstIterator E = _script_class_icon_paths.find(current);
|
||||
if ((bool)E && !E->value.is_empty()) {
|
||||
if (r_valid) {
|
||||
*r_valid = true;
|
||||
}
|
||||
return E->value;
|
||||
}
|
||||
current = ScriptServer::get_global_class_base(current);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
StringName EditorData::script_class_get_name(const String &p_path) const {
|
||||
|
|
@ -1052,24 +1046,23 @@ void EditorData::script_class_set_name(const String &p_path, const StringName &p
|
|||
_script_class_file_to_path[p_path] = p_class;
|
||||
}
|
||||
|
||||
void EditorData::script_class_save_icon_paths() {
|
||||
Array script_classes = ProjectSettings::get_singleton()->get_global_class_list();
|
||||
|
||||
Dictionary d;
|
||||
for (const KeyValue<StringName, String> &E : _script_class_icon_paths) {
|
||||
if (ScriptServer::is_global_class(E.key)) {
|
||||
d[E.key] = E.value;
|
||||
}
|
||||
void EditorData::script_class_save_global_classes() {
|
||||
List<StringName> global_classes;
|
||||
ScriptServer::get_global_class_list(&global_classes);
|
||||
Array array_classes;
|
||||
for (const StringName &class_name : global_classes) {
|
||||
Dictionary d;
|
||||
String *icon = _script_class_icon_paths.getptr(class_name);
|
||||
d["class"] = class_name;
|
||||
d["language"] = ScriptServer::get_global_class_language(class_name);
|
||||
d["path"] = ScriptServer::get_global_class_path(class_name);
|
||||
d["base"] = ScriptServer::get_global_class_base(class_name);
|
||||
d["icon"] = icon ? *icon : String();
|
||||
d["is_abstract"] = ScriptServer::is_global_class_abstract(class_name);
|
||||
d["is_tool"] = ScriptServer::is_global_class_tool(class_name);
|
||||
array_classes.push_back(d);
|
||||
}
|
||||
|
||||
for (int i = 0; i < script_classes.size(); i++) {
|
||||
Dictionary d2 = script_classes[i];
|
||||
if (!d2.has("class")) {
|
||||
continue;
|
||||
}
|
||||
d2["icon"] = d.get(d2["class"], "");
|
||||
}
|
||||
ProjectSettings::get_singleton()->store_global_class_list(script_classes);
|
||||
ProjectSettings::get_singleton()->store_global_class_list(array_classes);
|
||||
}
|
||||
|
||||
void EditorData::script_class_load_icon_paths() {
|
||||
|
|
@ -1126,28 +1119,42 @@ Ref<Texture2D> EditorData::_load_script_icon(const String &p_path) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<Texture2D> EditorData::get_script_icon(const Ref<Script> &p_script) {
|
||||
Ref<Texture2D> EditorData::get_script_icon(const String &p_script_path) {
|
||||
// Take from the local cache, if available.
|
||||
if (_script_icon_cache.has(p_script)) {
|
||||
if (_script_icon_cache.has(p_script_path)) {
|
||||
// Can be an empty value if we can't resolve any icon for this script.
|
||||
// An empty value is still cached to avoid unnecessary attempts at resolving it again.
|
||||
return _script_icon_cache[p_script];
|
||||
return _script_icon_cache[p_script_path];
|
||||
}
|
||||
|
||||
Ref<Script> base_scr = p_script;
|
||||
// Fast path in case the whole hierarchy is made of global classes.
|
||||
StringName class_name = script_class_get_name(p_script_path);
|
||||
{
|
||||
if (class_name != StringName()) {
|
||||
bool icon_valid = false;
|
||||
String icon_path = script_class_get_icon_path(class_name, &icon_valid);
|
||||
if (icon_valid) {
|
||||
Ref<Texture2D> icon = _load_script_icon(icon_path);
|
||||
_script_icon_cache[p_script_path] = icon;
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Script> base_scr = ResourceLoader::load(p_script_path, "Script");
|
||||
while (base_scr.is_valid()) {
|
||||
// Check for scripted classes.
|
||||
String icon_path;
|
||||
StringName class_name = script_class_get_name(base_scr->get_path());
|
||||
if (base_scr->is_built_in() || class_name == StringName()) {
|
||||
StringName base_class_name = script_class_get_name(base_scr->get_path());
|
||||
if (base_scr->is_built_in() || base_class_name == StringName()) {
|
||||
icon_path = base_scr->get_class_icon_path();
|
||||
} else {
|
||||
icon_path = script_class_get_icon_path(class_name);
|
||||
icon_path = script_class_get_icon_path(base_class_name);
|
||||
}
|
||||
|
||||
Ref<Texture2D> icon = _load_script_icon(icon_path);
|
||||
if (icon.is_valid()) {
|
||||
_script_icon_cache[p_script] = icon;
|
||||
_script_icon_cache[p_script_path] = icon;
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
|
@ -1155,7 +1162,7 @@ Ref<Texture2D> EditorData::get_script_icon(const Ref<Script> &p_script) {
|
|||
// TODO: Should probably be deprecated in 4.x
|
||||
const EditorData::CustomType *ctype = get_custom_type_by_path(base_scr->get_path());
|
||||
if (ctype && ctype->icon.is_valid()) {
|
||||
_script_icon_cache[p_script] = ctype->icon;
|
||||
_script_icon_cache[p_script_path] = ctype->icon;
|
||||
return ctype->icon;
|
||||
}
|
||||
|
||||
|
|
@ -1163,21 +1170,16 @@ Ref<Texture2D> EditorData::get_script_icon(const Ref<Script> &p_script) {
|
|||
base_scr = base_scr->get_base_script();
|
||||
}
|
||||
|
||||
// No custom icon was found in the inheritance chain, so check the base
|
||||
// class of the script instead.
|
||||
String base_type;
|
||||
p_script->get_language()->get_global_class_name(p_script->get_path(), &base_type);
|
||||
|
||||
// Check if the base type is an extension-defined type.
|
||||
Ref<Texture2D> ext_icon = extension_class_get_icon(base_type);
|
||||
Ref<Texture2D> ext_icon = extension_class_get_icon(class_name);
|
||||
if (ext_icon.is_valid()) {
|
||||
_script_icon_cache[p_script] = ext_icon;
|
||||
_script_icon_cache[p_script_path] = ext_icon;
|
||||
return ext_icon;
|
||||
}
|
||||
|
||||
// If no icon found, cache it as null.
|
||||
_script_icon_cache[p_script] = Ref<Texture>();
|
||||
return nullptr;
|
||||
_script_icon_cache[p_script_path] = Ref<Texture2D>();
|
||||
return Ref<Texture2D>();
|
||||
}
|
||||
|
||||
void EditorData::clear_script_icon_cache() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue