Просмотр исходного кода

PackedScene: Use ObjectID for DeferredNodePathProperties base

Help do proper error handling and avoid a crash.

Works around #103263.

(cherry picked from commit dbdd8a2db922811d8c5975797e44844979801c6d)
Rémi Verschelde 6 месяцев назад
Родитель
Сommit
309c371c0a
2 измененных файлов с 14 добавлено и 12 удалено
  1. 13 11
      scene/resources/packed_scene.cpp
  2. 1 1
      scene/resources/packed_scene.h

+ 13 - 11
scene/resources/packed_scene.cpp

@@ -328,7 +328,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
 
 
 						DeferredNodePathProperties dnp;
 						DeferredNodePathProperties dnp;
 						dnp.value = props[nprops[j].value];
 						dnp.value = props[nprops[j].value];
-						dnp.base = node;
+						dnp.base = node->get_instance_id();
 						dnp.property = snames[name_idx];
 						dnp.property = snames[name_idx];
 						deferred_node_paths.push_back(dnp);
 						deferred_node_paths.push_back(dnp);
 						continue;
 						continue;
@@ -521,25 +521,27 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
 
 
 	for (const DeferredNodePathProperties &dnp : deferred_node_paths) {
 	for (const DeferredNodePathProperties &dnp : deferred_node_paths) {
 		// Replace properties stored as NodePaths with actual Nodes.
 		// Replace properties stored as NodePaths with actual Nodes.
+		Node *base = Object::cast_to<Node>(ObjectDB::get_instance(dnp.base));
+		ERR_CONTINUE_EDMSG(!base, vformat("Failed to set deferred property '%s' as the base node disappeared.", dnp.property));
 		if (dnp.value.get_type() == Variant::ARRAY) {
 		if (dnp.value.get_type() == Variant::ARRAY) {
 			Array paths = dnp.value;
 			Array paths = dnp.value;
 
 
 			bool valid;
 			bool valid;
-			Array array = dnp.base->get(dnp.property, &valid);
-			ERR_CONTINUE_EDMSG(!valid, vformat("Failed to get property '%s' from node '%s'.", dnp.property, dnp.base->get_name()));
+			Array array = base->get(dnp.property, &valid);
+			ERR_CONTINUE_EDMSG(!valid, vformat("Failed to get property '%s' from node '%s'.", dnp.property, base->get_name()));
 			array = array.duplicate();
 			array = array.duplicate();
 
 
 			array.resize(paths.size());
 			array.resize(paths.size());
 			for (int i = 0; i < array.size(); i++) {
 			for (int i = 0; i < array.size(); i++) {
-				array.set(i, dnp.base->get_node_or_null(paths[i]));
+				array.set(i, base->get_node_or_null(paths[i]));
 			}
 			}
-			dnp.base->set(dnp.property, array);
+			base->set(dnp.property, array);
 		} else if (dnp.value.get_type() == Variant::DICTIONARY) {
 		} else if (dnp.value.get_type() == Variant::DICTIONARY) {
 			Dictionary paths = dnp.value;
 			Dictionary paths = dnp.value;
 
 
 			bool valid;
 			bool valid;
-			Dictionary dict = dnp.base->get(dnp.property, &valid);
-			ERR_CONTINUE_EDMSG(!valid, vformat("Failed to get property '%s' from node '%s'.", dnp.property, dnp.base->get_name()));
+			Dictionary dict = base->get(dnp.property, &valid);
+			ERR_CONTINUE_EDMSG(!valid, vformat("Failed to get property '%s' from node '%s'.", dnp.property, base->get_name()));
 			dict = dict.duplicate();
 			dict = dict.duplicate();
 			bool convert_key = dict.get_typed_key_builtin() == Variant::OBJECT &&
 			bool convert_key = dict.get_typed_key_builtin() == Variant::OBJECT &&
 					ClassDB::is_parent_class(dict.get_typed_key_class_name(), "Node");
 					ClassDB::is_parent_class(dict.get_typed_key_class_name(), "Node");
@@ -549,17 +551,17 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
 			for (int i = 0; i < paths.size(); i++) {
 			for (int i = 0; i < paths.size(); i++) {
 				Variant key = paths.get_key_at_index(i);
 				Variant key = paths.get_key_at_index(i);
 				if (convert_key) {
 				if (convert_key) {
-					key = dnp.base->get_node_or_null(key);
+					key = base->get_node_or_null(key);
 				}
 				}
 				Variant value = paths.get_value_at_index(i);
 				Variant value = paths.get_value_at_index(i);
 				if (convert_value) {
 				if (convert_value) {
-					value = dnp.base->get_node_or_null(value);
+					value = base->get_node_or_null(value);
 				}
 				}
 				dict[key] = value;
 				dict[key] = value;
 			}
 			}
-			dnp.base->set(dnp.property, dict);
+			base->set(dnp.property, dict);
 		} else {
 		} else {
-			dnp.base->set(dnp.property, dnp.base->get_node_or_null(dnp.value));
+			base->set(dnp.property, base->get_node_or_null(dnp.value));
 		}
 		}
 	}
 	}
 
 

+ 1 - 1
scene/resources/packed_scene.h

@@ -70,7 +70,7 @@ class SceneState : public RefCounted {
 	};
 	};
 
 
 	struct DeferredNodePathProperties {
 	struct DeferredNodePathProperties {
-		Node *base = nullptr;
+		ObjectID base;
 		StringName property;
 		StringName property;
 		Variant value;
 		Variant value;
 	};
 	};