diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-28 12:56:30 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-28 12:58:15 +0300 |
commit | fddfc416ef10fc71a28f20bc0cef0a9e522de985 (patch) | |
tree | 26d942d55deea68d710ff2355907904dd09d2f40 /source/blender | |
parent | f827ab1d0c04bbd7328e96d762a1031948010be1 (diff) |
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).
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 99 |
2 files changed, 94 insertions, 15 deletions
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,13 +4826,51 @@ 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. * * To be used when complex operations over path are needed, like e.g. get relative paths, to avoid too much @@ -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) |