diff options
author | Bastien Montagne <bastien@blender.org> | 2020-04-25 21:58:55 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-04-28 16:25:19 +0300 |
commit | 9f090bac5c7455ab22cd22cc3f6ea94b54d6de33 (patch) | |
tree | c434f5958335b1f4be6f2de7aba8c240ed8bc1e6 | |
parent | 7d85b6431fc331d9869f945bf7c9f3353b7b8c95 (diff) |
IDProperties: add a foreach looper and use it in libquery code.
Note: part of fix for T75279.
Differential Revision: https://developer.blender.org/D7550
-rw-r--r-- | source/blender/blenkernel/BKE_idprop.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/idprop.c | 41 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_query.c | 57 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 12 |
4 files changed, 86 insertions, 35 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 2b02895043f..1272127daa0 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -179,6 +179,17 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference); # define IDP_Id(prop) ((ID *)(prop)->data.pointer) #endif +/** + * Call a callback for each idproperty in the hierarchy under given root one (included). + * + */ +typedef void (*IDPForeachPropertyCallback)(IDProperty *id_property, void *user_data); + +void IDP_foreach_property(struct IDProperty *id_property_root, + const int type_filter, + IDPForeachPropertyCallback callback, + void *user_data); + /* Format IDProperty as strings */ char *IDP_reprN(const struct IDProperty *prop, uint *r_len); void IDP_repr_fn(const IDProperty *prop, diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 5530a126ffc..669539ca574 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -1130,4 +1130,45 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference) } } +/** + * Loop through all ID properties in hierarchy of given \a id_property_root included. + * + * \note Container types (groups and arrays) are processed after applying the callback on them. + * + * \param type_filter: If not 0, only apply callback on properties of matching types, see + * IDP_TYPE_FILTER_ enum in DNA_ID.h. + */ +void IDP_foreach_property(IDProperty *id_property_root, + const int type_filter, + IDPForeachPropertyCallback callback, + void *user_data) +{ + if (!id_property_root) { + return; + } + + if (type_filter == 0 || (1 << id_property_root->type) & type_filter) { + callback(id_property_root, user_data); + } + + /* Recursive call into container types of ID properties. */ + switch (id_property_root->type) { + case IDP_GROUP: { + LISTBASE_FOREACH (IDProperty *, loop, &id_property_root->data.group) { + IDP_foreach_property(loop, type_filter, callback, user_data); + } + break; + } + case IDP_IDPARRAY: { + IDProperty *loop = IDP_Array(id_property_root); + for (int i = 0; i < id_property_root->len; i++) { + IDP_foreach_property(&loop[i], type_filter, callback, user_data); + } + break; + } + default: + break; /* Nothing to do here with other types of IDProperties... */ + } +} + /** \} */ diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 4ffdcf14fa7..c93aade7cfa 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -172,34 +172,12 @@ static void library_foreach_ID_link(Main *bmain, int flag, LibraryForeachIDData *inherit_data); -static void library_foreach_idproperty_ID_link(LibraryForeachIDData *data, - IDProperty *prop, - int flag) +static void library_foreach_idpropertiesForeachIDLink(IDProperty *id_prop, void *user_data) { - if (!prop) { - return; - } + BLI_assert(id_prop->type == IDP_ID); - switch (prop->type) { - case IDP_GROUP: { - LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) { - library_foreach_idproperty_ID_link(data, loop, flag); - } - break; - } - case IDP_IDPARRAY: { - IDProperty *loop = IDP_Array(prop); - for (int i = 0; i < prop->len; i++) { - library_foreach_idproperty_ID_link(data, &loop[i], flag); - } - break; - } - case IDP_ID: - FOREACH_CALLBACK_INVOKE_ID(data, prop->data.pointer, flag); - break; - default: - break; /* Nothing to do here with other types of IDProperties... */ - } + LibraryForeachIDData *data = (LibraryForeachIDData *)user_data; + FOREACH_CALLBACK_INVOKE_ID(data, id_prop->data.pointer, IDWALK_CB_USER); FOREACH_FINALIZE_VOID; } @@ -336,7 +314,8 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint) static void library_foreach_bone(LibraryForeachIDData *data, Bone *bone) { - library_foreach_idproperty_ID_link(data, bone->prop, IDWALK_CB_USER); + IDP_foreach_property( + bone->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, data); LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) { library_foreach_bone(data, curbone); @@ -642,7 +621,8 @@ static void library_foreach_ID_link(Main *bmain, IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE); } - library_foreach_idproperty_ID_link(&data, id->properties, IDWALK_CB_USER); + IDP_foreach_property( + id->properties, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); AnimData *adt = BKE_animdata_from_id(id); if (adt) { @@ -678,7 +658,8 @@ static void library_foreach_ID_link(Main *bmain, CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER); CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER); CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER); - library_foreach_idproperty_ID_link(&data, seq->prop, IDWALK_CB_USER); + IDP_foreach_property( + seq->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) { CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER); } @@ -836,7 +817,8 @@ static void library_foreach_ID_link(Main *bmain, data.cb_flag |= proxy_cb_flag; for (pchan = object->pose->chanbase.first; pchan; pchan = pchan->next) { - library_foreach_idproperty_ID_link(&data, pchan->prop, IDWALK_CB_USER); + IDP_foreach_property( + pchan->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER); BKE_constraints_id_loop( &pchan->constraints, library_foreach_constraintObjectLooper, &data); @@ -1024,20 +1006,25 @@ static void library_foreach_ID_link(Main *bmain, for (node = ntree->nodes.first; node; node = node->next) { CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER); - library_foreach_idproperty_ID_link(&data, node->prop, IDWALK_CB_USER); + IDP_foreach_property( + node->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); for (sock = node->inputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + IDP_foreach_property( + sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); } for (sock = node->outputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + IDP_foreach_property( + sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); } } for (sock = ntree->inputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + IDP_foreach_property( + sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); } for (sock = ntree->outputs.first; sock; sock = sock->next) { - library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER); + IDP_foreach_property( + sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data); } break; } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index d6d3628cc66..5230cb050f4 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -106,6 +106,18 @@ enum { IDP_NUMTYPES = 10, }; +/** Used by some IDP utils, keep values in sync with type enum above. */ +enum { + IDP_TYPE_FILTER_STRING = 1 << 0, + IDP_TYPE_FILTER_INT = 1 << 1, + IDP_TYPE_FILTER_FLOAT = 1 << 2, + IDP_TYPE_FILTER_ARRAY = 1 << 5, + IDP_TYPE_FILTER_GROUP = 1 << 6, + IDP_TYPE_FILTER_ID = 1 << 7, + IDP_TYPE_FILTER_DOUBLE = 1 << 8, + IDP_TYPE_FILTER_IDPARRAY = 1 << 9, +}; + /*->subtype */ /* IDP_STRING */ |