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

Merge pull request #88426 from Rindbee/fix-inherited-scenes-produce-errors

Fix inherited scenes produce errors in editor when `editable_children` is true
Rémi Verschelde 1 год назад
Родитель
Сommit
1d6403323f
3 измененных файлов с 32 добавлено и 18 удалено
  1. 4 4
      scene/property_utils.cpp
  2. 27 13
      scene/resources/packed_scene.cpp
  3. 1 1
      scene/resources/packed_scene.h

+ 4 - 4
scene/property_utils.cpp

@@ -73,15 +73,15 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
 		for (int i = 0; i < states_stack.size(); ++i) {
 			const SceneState::PackState &ia = states_stack[i];
 			bool found = false;
-			Variant value_in_ancestor = ia.state->get_property_value(ia.node, p_property, found);
-			const Vector<String> &deferred_properties = ia.state->get_node_deferred_nodepath_properties(ia.node);
+			bool node_deferred = false;
+			Variant value_in_ancestor = ia.state->get_property_value(ia.node, p_property, found, node_deferred);
 			if (found) {
 				if (r_is_valid) {
 					*r_is_valid = true;
 				}
 				// Replace properties stored as NodePaths with actual Nodes.
 				// Otherwise, the property value would be considered as overridden.
-				if (deferred_properties.has(p_property)) {
+				if (node_deferred) {
 					if (value_in_ancestor.get_type() == Variant::ARRAY) {
 						Array paths = value_in_ancestor;
 
@@ -103,7 +103,7 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
 			}
 			// Save script for later
 			bool has_script = false;
-			Variant script = ia.state->get_property_value(ia.node, SNAME("script"), has_script);
+			Variant script = ia.state->get_property_value(ia.node, SNAME("script"), has_script, node_deferred);
 			if (has_script) {
 				Ref<Script> scr = script;
 				if (scr.is_valid()) {

+ 27 - 13
scene/resources/packed_scene.cpp

@@ -1310,29 +1310,31 @@ int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
 	return -1;
 }
 
-Variant SceneState::get_property_value(int p_node, const StringName &p_property, bool &found) const {
-	found = false;
+Variant SceneState::get_property_value(int p_node, const StringName &p_property, bool &r_found, bool &r_node_deferred) const {
+	r_found = false;
+	r_node_deferred = false;
 
 	ERR_FAIL_COND_V(p_node < 0, Variant());
 
 	if (p_node < nodes.size()) {
-		//find in built-in nodes
+		// Find in built-in nodes.
 		int pc = nodes[p_node].properties.size();
 		const StringName *namep = names.ptr();
 
 		const NodeData::Property *p = nodes[p_node].properties.ptr();
 		for (int i = 0; i < pc; i++) {
 			if (p_property == namep[p[i].name & FLAG_PROP_NAME_MASK]) {
-				found = true;
+				r_found = true;
+				r_node_deferred = p[i].name & FLAG_PATH_PROPERTY_IS_NODE;
 				return variants[p[i].value];
 			}
 		}
 	}
 
-	//property not found, try on instance
-
-	if (base_scene_node_remap.has(p_node)) {
-		return get_base_scene_state()->get_property_value(base_scene_node_remap[p_node], p_property, found);
+	// Property not found, try on instance.
+	HashMap<int, int>::ConstIterator I = base_scene_node_remap.find(p_node);
+	if (I) {
+		return get_base_scene_state()->get_property_value(I->value, p_property, r_found, r_node_deferred);
 	}
 
 	return Variant();
@@ -1722,13 +1724,25 @@ StringName SceneState::get_node_property_name(int p_idx, int p_prop) const {
 
 Vector<String> SceneState::get_node_deferred_nodepath_properties(int p_idx) const {
 	Vector<String> ret;
-	ERR_FAIL_INDEX_V(p_idx, nodes.size(), ret);
-	for (int i = 0; i < nodes[p_idx].properties.size(); i++) {
-		uint32_t idx = nodes[p_idx].properties[i].name;
-		if (idx & FLAG_PATH_PROPERTY_IS_NODE) {
-			ret.push_back(names[idx & FLAG_PROP_NAME_MASK]);
+	ERR_FAIL_COND_V(p_idx < 0, ret);
+
+	if (p_idx < nodes.size()) {
+		// Find in built-in nodes.
+		for (int i = 0; i < nodes[p_idx].properties.size(); i++) {
+			uint32_t idx = nodes[p_idx].properties[i].name;
+			if (idx & FLAG_PATH_PROPERTY_IS_NODE) {
+				ret.push_back(names[idx & FLAG_PROP_NAME_MASK]);
+			}
 		}
+		return ret;
 	}
+
+	// Property not found, try on instance.
+	HashMap<int, int>::ConstIterator I = base_scene_node_remap.find(p_idx);
+	if (I) {
+		return get_base_scene_state()->get_node_deferred_nodepath_properties(I->value);
+	}
+
 	return ret;
 }
 

+ 1 - 1
scene/resources/packed_scene.h

@@ -139,7 +139,7 @@ public:
 	static Ref<Resource> get_remap_resource(const Ref<Resource> &p_resource, HashMap<Ref<Resource>, Ref<Resource>> &remap_cache, const Ref<Resource> &p_fallback, Node *p_for_scene);
 
 	int find_node_by_path(const NodePath &p_node) const;
-	Variant get_property_value(int p_node, const StringName &p_property, bool &found) const;
+	Variant get_property_value(int p_node, const StringName &p_property, bool &r_found, bool &r_node_deferred) const;
 	bool is_node_in_group(int p_node, const StringName &p_group) const;
 	bool is_connection(int p_node, const StringName &p_signal, int p_to_node, const StringName &p_to_method) const;