Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-03-11 17:57:11 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-03-11 17:58:53 +0400
commita6bdad699c77209a6ff84a2ec80693feaf9012d0 (patch)
tree3bc4e29ae64ea8efd151664e45eef6943c5ce64e /source/blender/makesrna
parent89c793f70f2cc65c7ae2a903a8b747a3fb799f38 (diff)
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
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r--source/blender/makesrna/RNA_access.h6
-rw-r--r--source/blender/makesrna/intern/rna_access.c150
2 files changed, 99 insertions, 57 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index ed33098858f..f385d61601a 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 7138f97bf9a..51e01d93799 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)
{