1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-08 12:40:44 +00:00

Store _custom_type_script meta as String

This commit is contained in:
kobewi
2025-02-12 00:51:22 +01:00
parent ad9abe841d
commit 38d0e82a35
5 changed files with 49 additions and 15 deletions

View File

@@ -39,6 +39,7 @@
#include "editor/multi_node_edit.h"
#include "editor/plugins/editor_context_menu_plugin.h"
#include "editor/plugins/editor_plugin.h"
#include "scene/property_utils.h"
#include "scene/resources/packed_scene.h"
void EditorSelectionHistory::cleanup_history() {
@@ -536,15 +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);
}
n->set_meta(SceneStringName(_custom_type_script), script);
((Object *)ob)->set_script(script);
return ob;
PropertyUtils::assign_custom_type_script(ob, script);
ob->set_script(script);
return v;
}
}
}
@@ -988,12 +992,13 @@ Variant EditorData::script_class_instance(const String &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) {
Object::cast_to<Object>(obj)->set_meta(SceneStringName(_custom_type_script), script);
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();

View File

@@ -4751,7 +4751,7 @@ Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) cons
const Node *node = Object::cast_to<const Node>(p_object);
if (node && node->has_meta(SceneStringName(_custom_type_script))) {
return node->get_meta(SceneStringName(_custom_type_script));
return PropertyUtils::get_custom_type_script(node);
}
Ref<Script> scr = p_object->get_script();

View File

@@ -2834,7 +2834,7 @@ void SceneTreeDock::_update_script_button() {
Ref<Script> cts;
if (n->has_meta(SceneStringName(_custom_type_script))) {
cts = n->get_meta(SceneStringName(_custom_type_script));
cts = PropertyUtils::get_custom_type_script(n);
}
if (selection.size() == 1) {
@@ -3114,7 +3114,7 @@ void SceneTreeDock::_replace_node(Node *p_node, Node *p_by_node, bool p_keep_pro
// If we're dealing with a custom node type, we need to create a default instance of the custom type instead of the native type for property comparison.
if (oldnode->has_meta(SceneStringName(_custom_type_script))) {
Ref<Script> cts = oldnode->get_meta(SceneStringName(_custom_type_script));
Ref<Script> cts = PropertyUtils::get_custom_type_script(oldnode);
default_oldnode = Object::cast_to<Node>(get_editor_data()->script_class_instance(cts->get_global_name()));
if (default_oldnode) {
default_oldnode->set_name(cts->get_global_name());
@@ -3618,7 +3618,7 @@ void SceneTreeDock::_script_dropped(const String &p_file, NodePath p_to) {
} else {
// Check if dropped script is compatible.
if (n->has_meta(SceneStringName(_custom_type_script))) {
Ref<Script> ct_scr = n->get_meta(SceneStringName(_custom_type_script));
Ref<Script> ct_scr = PropertyUtils::get_custom_type_script(n);
if (!scr->inherits_script(ct_scr)) {
String custom_type_name = ct_scr->get_global_name();

View File

@@ -92,7 +92,7 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
// Handle special case "script" property, where the default value is either null or the custom type script.
// Do this only if there's no states stack cache to trace for default values.
if (!p_states_stack_cache && p_property == CoreStringName(script) && p_object->has_meta(SceneStringName(_custom_type_script))) {
Ref<Script> ct_scr = p_object->get_meta(SceneStringName(_custom_type_script));
Ref<Script> ct_scr = get_custom_type_script(p_object);
if (r_is_valid) {
*r_is_valid = true;
}
@@ -282,3 +282,29 @@ Vector<SceneState::PackState> PropertyUtils::get_node_states_stack(const Node *p
}
return states_stack_ret;
}
void PropertyUtils::assign_custom_type_script(Object *p_object, const Ref<Script> &p_script) {
ERR_FAIL_NULL(p_object);
ERR_FAIL_COND(p_script.is_null());
const String &path = p_script->get_path();
ERR_FAIL_COND(!path.is_resource_file());
ResourceUID::ID script_uid = ResourceLoader::get_resource_uid(path);
if (script_uid != ResourceUID::INVALID_ID) {
p_object->set_meta(SceneStringName(_custom_type_script), ResourceUID::get_singleton()->id_to_text(script_uid));
}
}
Ref<Script> PropertyUtils::get_custom_type_script(const Object *p_object) {
Variant custom_script = p_object->get_meta(SceneStringName(_custom_type_script));
#ifndef DISABLE_DEPRECATED
if (custom_script.get_type() == Variant::OBJECT) {
// Convert old script meta.
Ref<Script> script_object(custom_script);
assign_custom_type_script(const_cast<Object *>(p_object), script_object);
return script_object;
}
#endif
return ResourceLoader::load(custom_script);
}

View File

@@ -46,6 +46,9 @@ public:
// in the tree, since every owner found while traversing towards the root gets a chance
// to override property values.)
static Vector<SceneState::PackState> get_node_states_stack(const Node *p_node, const Node *p_owner = nullptr, bool *r_instantiated_by_owner = nullptr);
static void assign_custom_type_script(Object *p_object, const Ref<Script> &p_script);
static Ref<Script> get_custom_type_script(const Object *p_object);
};
#endif // PROPERTY_UTILS_H