IDProperties: add a foreach looper and use it in libquery code.
Note: part of fix for T75279. Differential Revision: https://developer.blender.org/D7550
This commit is contained in:
parent
7d85b6431f
commit
9f090bac5c
|
@ -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,
|
||||
|
|
|
@ -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... */
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue