[Bf-blender-cvs] [a6bdad6] master: Fix T39080: copy-to-selected operator fails for pointer properties.

Lukas Tönne noreply at git.blender.org
Tue Mar 11 15:04:17 CET 2014


Commit: a6bdad699c77209a6ff84a2ec80693feaf9012d0
Author: Lukas Tönne
Date:   Tue Mar 11 14:57:11 2014 +0100
https://developer.blender.org/rBa6bdad699c77209a6ff84a2ec80693feaf9012d0

Fix T39080: copy-to-selected operator fails for pointer properties.

The copy-to-selected operator for RNA buttons uses paths for copying
object pointer properties. Copying other ID data blocks is deliberately
disabled:
https://developer.blender.org/diffusion/B/browse/master/source/blender/editors/interface/interface_ops.c$274

However, the RNA_path_resolve_full function is not properly working for
retrieving pointer properties: it always will dereference pointer
properties in anticipation of further path elements.

In fact the return value of RNA_path_resolve_full has a conflicting
double meaning. It returns `false` when
* the RNA path is invalid
* any of the pointer properties is NULL

This means that it is not capable of returning pointer properties at all.
To make this possible, there is now an internal function for path
parsing, which returns false //only// if the the path is invalid.
On top of this there are 4 wrapper functions for retrieving either
actual property values (RNA_path_resolve, RNA_path_resolve_full) and for
retrieving pointer+property pairs (RNA_path_resolve_property,
RNA_path_resolve_property_full). The latter 2 variants will **not**
dereference pointer properties at the end of the path, so callers can
actually get the property itself. The `***_full` variants include an
array index return value.

Differential Revision: https://developer.blender.org/D396

===================================================================

M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_access.c

===================================================================

diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index ed33098..f385d61 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -914,14 +914,14 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path,
                      PointerRNA *r_ptr, PropertyRNA **r_prop);
 
 bool RNA_path_resolve_full(PointerRNA *ptr, const char *path,
-                          PointerRNA *r_ptr, PropertyRNA **r_prop, int *index);
+                           PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
 
 /* path_resolve_property() variants ensure that pointer + property both exist */
 bool RNA_path_resolve_property(PointerRNA *ptr, const char *path,
-                     PointerRNA *r_ptr, PropertyRNA **r_prop);
+                               PointerRNA *r_ptr, PropertyRNA **r_prop);
 
 bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path,
-                          PointerRNA *r_ptr, PropertyRNA **r_prop, int *index);
+                                    PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
 
 char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7138f97..51e01d9 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -3873,40 +3873,13 @@ static int rna_token_strip_quotes(char *token)
 	return 0;
 }
 
-/* Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path
- * ! This is a convenience method to avoid logic errors and ugly syntax
- * ! Assumes all pointers provided are valid
- * > returns: True only if both a valid pointer and property are found after resolving the path 
- */
-bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
-{
-	return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL) && (*r_prop != NULL);
-}
-
-/* Resolve the given RNA Path to find the pointer AND property (as well as the array index) indicated by fully resolving the path
- * ! This is a convenience method to avoid logic errors and ugly syntax
- * ! Assumes all pointers provided are valid
- * > returns: True only if both a valid pointer and property are found after resolving the path
- */
-bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
-{
-	return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, index) && (*r_prop != NULL);
-}
-
-/* Resolve the given RNA Path to find the pointer and/or property indicated by fully resolving the path 
- * ! Assumes all pointers provided are valid
- * > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
- */
-bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
-{
-	return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
-}
-
-static bool rna_path_resolve_collection_key(const char **path, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_nextptr)
+static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_nextptr)
 {
 	char fixedbuf[256], *token;
 	int intkey;
 	
+	*r_nextptr = *ptr;
+
 	/* end of path, ok */
 	if (!(**path))
 		return true;
@@ -3955,10 +3928,10 @@ static bool rna_path_resolve_collection_key(const char **path, PointerRNA *ptr,
 		}
 	}
 	
-	return r_nextptr->data != NULL;
+	return true;
 }
 
-static bool rna_path_resolve_array_index(const char **path, PointerRNA *ptr, PropertyRNA *prop, int *r_index)
+static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, PropertyRNA *prop, int *r_index)
 {
 	char fixedbuf[256], *token;
 	int index_arr[RNA_MAX_ARRAY_DIMENSION] = {0};
@@ -4041,15 +4014,12 @@ static bool rna_path_resolve_array_index(const char **path, PointerRNA *ptr, Pro
 	return true;
 }
 
-/* Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path 
- * ! Assumes all pointers provided are valid
- * > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
- */
-bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
+static bool rna_path_parse(PointerRNA *ptr, const char *path,
+                           PointerRNA *r_ptr, PropertyRNA **r_prop, int *index,
+                           const bool eval_pointer)
 {
 	PropertyRNA *prop;
 	PointerRNA curptr;
-	PointerRNA nextptr;  /* keep uninitialized, helps expose bugs in collection accessor functions */
 	char fixedbuf[256], *token;
 	int type;
 
@@ -4065,12 +4035,16 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
 		 * C.object["someprop"]
 		 */
 
+		if (!curptr.data)
+			return false;
+
 		/* look up property name in current struct */
 		token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
 
 		if (!token)
 			return false;
 
+		prop = NULL;
 		if (use_id_prop) { /* look up property name in current struct */
 			IDProperty *group = RNA_struct_idprops(&curptr, 0);
 			if (group && rna_token_strip_quotes(token))
@@ -4092,26 +4066,35 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
 		 * collection, otherwise return the property rna so that the
 		 * caller can read the value of the property itself */
 		switch (type) {
-			case PROP_POINTER:
-				nextptr = RNA_property_pointer_get(&curptr, prop);
-				if (nextptr.data == NULL)
-					return false;
-				
-				curptr = nextptr;
-				prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
-				if (index) *index = -1;
+			case PROP_POINTER: {
+				/* resolve pointer if further path elements follow
+				 * or explicitly requested
+				 */
+				if (eval_pointer || *path) {
+					PointerRNA nextptr = RNA_property_pointer_get(&curptr, prop);
+					
+					curptr = nextptr;
+					prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
+					if (index) *index = -1;
+				}
 				break;
-			case PROP_COLLECTION:
-				if (!rna_path_resolve_collection_key(&path, &curptr, prop, &nextptr))
-					return false;
-				
-				curptr = nextptr;
-				prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
-				if (index) *index = -1;
+			}
+			case PROP_COLLECTION: {
+				/* resolve pointer if further path elements follow or explicitly requested */
+				if (eval_pointer || *path) {
+					PointerRNA nextptr;
+					if (!rna_path_parse_collection_key(&path, &curptr, prop, &nextptr))
+						return false;
+					
+					curptr = nextptr;
+					prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
+					if (index) *index = -1;
+				}
 				break;
+			}
 			default:
 				if (index) {
-					if (!rna_path_resolve_array_index(&path, &curptr, prop, index))
+					if (!rna_path_parse_array_index(&path, &curptr, prop, index))
 						return false;
 				}
 				break;
@@ -4124,6 +4107,65 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
 	return true;
 }
 
+/**
+ * Resolve the given RNA Path to find the pointer and/or property indicated by fully resolving the path.
+ *
+ * \note Assumes all pointers provided are valid
+ * \return True if path can be resolved to a valid "pointer + property" OR "pointer only"
+ */
+bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, true))
+		return false;
+
+	return r_ptr->data != NULL;
+}
+
+/**
+ * Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path.
+ *
+ * \note Assumes all pointers provided are valid.
+ * \return True if path can be resolved to a valid "pointer + property" OR "pointer only"
+ */
+bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, true))
+		return false;
+
+	return r_ptr->data != NULL;
+}
+
+/**
+ * Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path.
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax.
+ * \note Assumes all pointers provided are valid
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, false))
+		return false;
+
+	return r_ptr->data != NULL && *r_prop != NULL;
+}
+
+/**
+ * Resolve the given RNA Path to find the pointer AND property (as well as the array index)
+ * indicated by fully resolving the path.
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax.
+ *  \note Assumes all pointers provided are valid
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, false))
+		return false;
+
+	return r_ptr->data != NULL && *r_prop != NULL;
+}
+
 
 char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *prop, int intkey, const char *strkey)
 {




More information about the Bf-blender-cvs mailing list