[Bf-blender-cvs] [fddfc416ef1] blender2.8: RNA path: add way to get both valid ptr/prop pair, and final item ptr.

Bastien Montagne noreply at git.blender.org
Thu Jun 28 12:03:37 CEST 2018


Commit: fddfc416ef10fc71a28f20bc0cef0a9e522de985
Author: Bastien Montagne
Date:   Thu Jun 28 11:56:30 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBfddfc416ef10fc71a28f20bc0cef0a9e522de985

RNA path: add way to get both valid ptr/prop pair, and final item ptr.

This will be much useful in some cases, at least in override area it is
needed (avoids searching again for the overriden item in a collection).

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

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 f6ef3e9efcd..4ec6107d676 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1007,6 +1007,16 @@ bool RNA_path_resolve_property(PointerRNA *ptr, const char *path,
 bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path,
                                     PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
 
+/* path_resolve_property_and_item_pointer() variants ensure that pointer + property both exist,
+ * and resolve last Pointer value if possible (Pointer prop or item of a Collection prop). */
+bool RNA_path_resolve_property_and_item_pointer(
+        PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop,
+        PointerRNA *r_item_ptr);
+
+bool RNA_path_resolve_property_and_item_pointer_full(
+        PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index,
+        PointerRNA *r_item_ptr);
+
 typedef struct PropertyElemRNA PropertyElemRNA;
 struct PropertyElemRNA {
 	PropertyElemRNA *next, *prev;
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 5e8e33e660f..328c0a40905 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4608,17 +4608,38 @@ static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, Prope
 	return true;
 }
 
+/**
+ * Generic rna path parser.
+ *
+ * \note All parameters besides \a ptr and \a path are optional.
+ *
+ * \param ptr The root of given RNA path.
+ * \param path The RNA path.
+ * \param r_ptr The final RNA data holding the last property in \a path.
+ * \param r_prop The final property of \a r_ptr, from \a path.
+ * \param r_index The final index in the \a r_prop, if defined by \a path.
+ * \param r_item_ptr Only valid for Pointer and Collection, return the actual value of the pointer,
+ *                   or of the collection item. Mutually exclusive with \a eval_pointer option.
+ * \param r_elements A list of \a PropertyElemRNA items
+ *                   (pairs of \a PointerRNA, \a PropertyRNA that represent the whole given \a path).
+ * \param eval_pointer If \a true, and \a path leads to a Pointer property, or an item in a Collection property,
+ *                     \a r_ptr will be set to the value of that property, and \a r_prop will be NULL.
+ *                     Mutually exclusive with \a r_item_ptr.
+ * \return \a true on success, \a false if the path is somehow invalid.
+ */
 static bool rna_path_parse(PointerRNA *ptr, const char *path,
                            PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index,
-                           ListBase *r_elements,
+                           PointerRNA *r_item_ptr, ListBase *r_elements,
                            const bool eval_pointer)
 {
+	BLI_assert(r_item_ptr == NULL || !eval_pointer);
 	PropertyRNA *prop;
-	PointerRNA curptr;
+	PointerRNA curptr, nextptr;
 	PropertyElemRNA *prop_elem = NULL;
 	int index = -1;
 	char fixedbuf[256];
 	int type;
+	const bool do_item_ptr = r_item_ptr != NULL && !eval_pointer;
 
 	prop = NULL;
 	curptr = *ptr;
@@ -4627,6 +4648,10 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
 		return false;
 
 	while (*path) {
+		if (do_item_ptr) {
+			RNA_POINTER_INVALIDATE(&nextptr);
+		}
+
 		int use_id_prop = (*path == '[') ? 1 : 0;
 		char *token;
 		/* custom property lookup ?
@@ -4680,9 +4705,11 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
 				/* resolve pointer if further path elements follow
 				 * or explicitly requested
 				 */
-				if (eval_pointer || *path != '\0') {
-					PointerRNA nextptr = RNA_property_pointer_get(&curptr, prop);
+				if (do_item_ptr || eval_pointer || *path != '\0') {
+					nextptr = RNA_property_pointer_get(&curptr, prop);
+				}
 
+				if (eval_pointer || *path != '\0') {
 					curptr = nextptr;
 					prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
 					index = -1;
@@ -4692,11 +4719,9 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
 			case PROP_COLLECTION: {
 				/* Resolve pointer if further path elements follow.
 				 * Note that if path is empty, rna_path_parse_collection_key will do nothing anyway,
-				 * so eval_pointer is of no use here (esp. as in this case, we want to keep found prop,
-				 * erasing it breaks operators - e.g. bpy.types.Operator.bl_rna.foobar errors...).
+				 * so do_item_ptr is of no use in that case.
 				 */
 				if (*path) {
-					PointerRNA nextptr;
 					if (!rna_path_parse_collection_key(&path, &curptr, prop, &nextptr)) {
 						return false;
 					}
@@ -4723,12 +4748,18 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
 		}
 	}
 
-	if (r_ptr)
+	if (r_ptr) {
 		*r_ptr = curptr;
-	if (r_prop)
+	}
+	if (r_prop) {
 		*r_prop = prop;
-	if (r_index)
+	}
+	if (r_index) {
 		*r_index = index;
+	}
+	if (r_item_ptr && do_item_ptr) {
+		*r_item_ptr = nextptr;
+	}
 
 	if (prop_elem && (prop_elem->ptr.data != curptr.data || prop_elem->prop != prop || prop_elem->index != index)) {
 		prop_elem = MEM_mallocN(sizeof(PropertyElemRNA), __func__);
@@ -4749,7 +4780,7 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
  */
 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, NULL, true))
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, NULL, true))
 		return false;
 
 	return r_ptr->data != NULL;
@@ -4763,7 +4794,7 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prop
  */
 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, NULL, true))
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, NULL, true))
 		return false;
 
 	return r_ptr->data != NULL;
@@ -4778,7 +4809,7 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
  */
 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, NULL, false)) {
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, NULL, false)) {
 		return false;
 	}
 
@@ -4795,12 +4826,50 @@ bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_
  */
 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, NULL, false))
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, NULL, false))
+		return false;
+
+	return r_ptr->data != NULL && *r_prop != NULL;
+}
+
+/**
+ * Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path,
+ * and get the value of the Pointer property (or item of the collection).
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax, it combines both \a RNA_path_resolve and
+ * \a RNA_path_resolve_property in a single call.
+ * \note Assumes all pointers provided are valid.
+ * \param r_item_pointer The final Pointer or Collection item value. You must check for its validity before use!
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property_and_item_pointer(
+        PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, PointerRNA *r_item_ptr)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, r_item_ptr, NULL, false)) {
 		return false;
+	}
 
 	return r_ptr->data != NULL && *r_prop != NULL;
 }
 
+/**
+ * Resolve the given RNA Path to find both the pointer AND property (as well as the array index)
+ * indicated by fully resolving the path, and get the value of the Pointer property (or item of the collection).
+ *
+ * This is a convenience method to avoid logic errors and ugly syntax, it combines both \a RNA_path_resolve_full and
+ * \a RNA_path_resolve_property_full in a single call.
+ * \note Assumes all pointers provided are valid.
+ * \param r_item_pointer The final Pointer or Collection item value. You must check for its validity before use!
+ * \return True only if both a valid pointer and property are found after resolving the path
+ */
+bool RNA_path_resolve_property_and_item_pointer_full(
+        PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index, PointerRNA *r_item_ptr)
+{
+	if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, r_item_ptr, NULL, false))
+		return false;
+
+	return r_ptr->data != NULL && *r_prop != NULL;
+}
 /**
  * Resolve the given RNA Path into a linked list of PropertyElemRNA's.
  *
@@ -4812,7 +4881,7 @@ bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRN
  */
 bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, ListBase *r_elements)
 {
-	return rna_path_parse(ptr, path, NULL, NULL, NULL, r_elements, false);
+	return rna_path_parse(ptr, path, NULL, NULL, NULL, NULL, r_elements, false);
 }
 
 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