Selaa lähdekoodia

Merge pull request #102737 from KoBeWi/uids_are_creeping_everywhere

Store `_custom_type_script` meta as String
Rémi Verschelde 8 kuukautta sitten
vanhempi
commit
c6b6278cbe
5 muutettua tiedostoa jossa 49 lisäystä ja 15 poistoa
  1. 15 10
      editor/editor_data.cpp
  2. 1 1
      editor/editor_node.cpp
  3. 3 3
      editor/scene_tree_dock.cpp
  4. 27 1
      scene/property_utils.cpp
  5. 3 0
      scene/property_utils.h

+ 15 - 10
editor/editor_data.cpp

@@ -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();

+ 1 - 1
editor/editor_node.cpp

@@ -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();

+ 3 - 3
editor/scene_tree_dock.cpp

@@ -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();
 

+ 27 - 1
scene/property_utils.cpp

@@ -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);
+}

+ 3 - 0
scene/property_utils.h

@@ -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