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:
-rw-r--r--source/blender/blenkernel/BKE_idtype.h9
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h28
-rw-r--r--source/blender/blenkernel/intern/lib_query.c107
3 files changed, 120 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 6dc504c2007..b6dfadd3b2a 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -33,6 +33,7 @@ extern "C" {
#endif
struct ID;
+struct LibraryForeachIDData;
struct Main;
/** IDTypeInfo.flags. */
@@ -60,6 +61,8 @@ typedef void (*IDTypeFreeDataFunction)(struct ID *id);
/** \param flag: See BKE_lib_id.h's LIB_ID_MAKELOCAL_... flags. */
typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const int flags);
+typedef void (*IDTypeForeachIDFunction)(struct ID *id, struct LibraryForeachIDData *data);
+
typedef struct IDTypeInfo {
/* ********** General IDType data. ********** */
@@ -121,6 +124,12 @@ typedef struct IDTypeInfo {
* `BKE_lib_id_make_local_generic()` is enough.
*/
IDTypeMakeLocalFunction make_local;
+
+ /**
+ * Called by `BKE_library_foreach_ID_link()` to apply a callback over all other ID usages (ID
+ * pointers) of given data-block.
+ */
+ IDTypeForeachIDFunction foreach_id;
} IDTypeInfo;
/* ********** Declaration of each IDTypeInfo. ********** */
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index 3aa27bf557c..353ee3bbf5a 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -40,6 +40,7 @@ extern "C" {
#endif
struct ID;
+struct IDProperty;
struct Main;
/* Tips for the callback for cases it's gonna to modify the pointer. */
@@ -126,6 +127,33 @@ enum {
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */
};
+typedef struct LibraryForeachIDData LibraryForeachIDData;
+
+bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
+ struct ID **id_pp,
+ int cb_flag);
+
+#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
+ { \
+ CHECK_TYPE_ANY((_id), ID *, void *); \
+ if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag))) { \
+ return; \
+ } \
+ } \
+ ((void)0)
+
+#define BKE_LIB_FOREACHID_PROCESS(_data, _id_super, _cb_flag) \
+ { \
+ CHECK_TYPE(&((_id_super)->id), ID *); \
+ if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
+ return; \
+ } \
+ } \
+ ((void)0)
+
+bool BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp);
+void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data);
+
/* Loop over all of the ID's this datablock links to. */
void BKE_library_foreach_ID_link(
struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 31ac8ca623b..7e73257d9e0 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -71,6 +71,7 @@
#include "BKE_fcurve_driver.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_idprop.h"
+#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
@@ -165,6 +166,38 @@ typedef struct LibraryForeachIDData {
BLI_LINKSTACK_DECLARE(ids_todo, ID *);
} LibraryForeachIDData;
+bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
+{
+ if (!(data->status & IDWALK_STOP)) {
+ const int flag = data->flag;
+ ID *old_id = *id_pp;
+ const int callback_return = data->callback(&(struct LibraryIDLinkCallbackData){
+ .user_data = data->user_data,
+ .id_owner = data->owner_id,
+ .id_self = data->self_id,
+ .id_pointer = id_pp,
+ .cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear)});
+ if (flag & IDWALK_READONLY) {
+ BLI_assert(*(id_pp) == old_id);
+ }
+ if (old_id && (flag & IDWALK_RECURSE)) {
+ if (BLI_gset_add((data)->ids_handled, old_id)) {
+ if (!(callback_return & IDWALK_RET_STOP_RECURSION)) {
+ BLI_LINKSTACK_PUSH(data->ids_todo, old_id);
+ }
+ }
+ }
+ if (callback_return & IDWALK_RET_STOP_ITER) {
+ data->status |= IDWALK_STOP;
+ return false;
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static void library_foreach_ID_link(Main *bmain,
ID *id_owner,
ID *id,
@@ -173,20 +206,18 @@ static void library_foreach_ID_link(Main *bmain,
int flag,
LibraryForeachIDData *inherit_data);
-static void library_foreach_idpropertiesForeachIDLink(IDProperty *id_prop, void *user_data)
+void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void *user_data)
{
BLI_assert(id_prop->type == IDP_ID);
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
-
- FOREACH_FINALIZE_VOID;
+ BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
}
static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock)
{
IDP_foreach_property(
- sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
+ sock->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, &data);
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
@@ -344,7 +375,7 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
static void library_foreach_bone(LibraryForeachIDData *data, Bone *bone)
{
IDP_foreach_property(
- bone->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, data);
+ bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
library_foreach_bone(data, curbone);
@@ -535,15 +566,21 @@ static void library_foreach_screen_area(LibraryForeachIDData *data, ScrArea *are
FOREACH_FINALIZE_VOID;
}
-static void library_foreach_ID_as_subdata_link(ID **id_pp, LibraryForeachIDData *data)
+bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
{
/* Needed e.g. for callbacks handling relationships... This call shall be absolutely readonly. */
ID *id = *id_pp;
const int flag = data->flag;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pp, IDWALK_CB_EMBEDDED);
+ if (!BKE_lib_query_foreachid_process(data, id_pp, IDWALK_CB_EMBEDDED)) {
+ return false;
+ }
BLI_assert(id == *id_pp);
+ if (id == NULL) {
+ return true;
+ }
+
if (flag & IDWALK_IGNORE_EMBEDDED_ID) {
/* Do Nothing. */
}
@@ -561,7 +598,7 @@ static void library_foreach_ID_as_subdata_link(ID **id_pp, LibraryForeachIDData
data->bmain, data->owner_id, id, data->callback, data->user_data, data->flag, data);
}
- FOREACH_FINALIZE_VOID;
+ return true;
}
static void library_foreach_ID_link(Main *bmain,
@@ -648,14 +685,30 @@ static void library_foreach_ID_link(Main *bmain,
IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
}
- IDP_foreach_property(
- id->properties, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
+ IDP_foreach_property(id->properties,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ &data);
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
library_foreach_animationData(&data, adt);
}
+ const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
+
+ /* Note: this is temp logic until all code has been ported to IDTypeInfo... */
+ if (id_type->foreach_id != NULL) {
+ id_type->foreach_id(id, &data);
+
+ if (data.status & IDWALK_STOP) {
+ break;
+ }
+ else {
+ continue;
+ }
+ }
+
switch ((ID_Type)GS(id->name)) {
case ID_LI: {
Library *lib = (Library *)id;
@@ -674,7 +727,7 @@ static void library_foreach_ID_link(Main *bmain,
CALLBACK_INVOKE(scene->r.bake.cage_object, IDWALK_CB_NOP);
if (scene->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&scene->nodetree);
}
if (scene->ed) {
Sequence *seq;
@@ -684,8 +737,10 @@ 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);
- IDP_foreach_property(
- seq->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
+ IDP_foreach_property(seq->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ &data);
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
}
@@ -839,8 +894,10 @@ static void library_foreach_ID_link(Main *bmain,
if (object->pose) {
data.cb_flag |= proxy_cb_flag;
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- IDP_foreach_property(
- pchan->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
+ IDP_foreach_property(pchan->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ &data);
CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
BKE_constraints_id_loop(
&pchan->constraints, library_foreach_constraintObjectLooper, &data);
@@ -927,7 +984,7 @@ static void library_foreach_ID_link(Main *bmain,
Material *material = (Material *)id;
if (material->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&material->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&material->nodetree);
}
if (material->texpaintslot != NULL) {
CALLBACK_INVOKE(material->texpaintslot->ima, IDWALK_CB_NOP);
@@ -943,7 +1000,7 @@ static void library_foreach_ID_link(Main *bmain,
Tex *texture = (Tex *)id;
if (texture->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&texture->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&texture->nodetree);
}
CALLBACK_INVOKE(texture->ima, IDWALK_CB_USER);
break;
@@ -959,7 +1016,7 @@ static void library_foreach_ID_link(Main *bmain,
Light *lamp = (Light *)id;
if (lamp->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&lamp->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&lamp->nodetree);
}
break;
}
@@ -989,7 +1046,7 @@ static void library_foreach_ID_link(Main *bmain,
World *world = (World *)id;
if (world->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&world->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&world->nodetree);
}
break;
}
@@ -1021,8 +1078,10 @@ static void library_foreach_ID_link(Main *bmain,
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER);
- IDP_foreach_property(
- node->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
+ IDP_foreach_property(node->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ &data);
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
library_foreach_node_socket(&data, sock);
}
@@ -1145,7 +1204,7 @@ static void library_foreach_ID_link(Main *bmain,
}
if (linestyle->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&linestyle->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&linestyle->nodetree);
}
LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
@@ -1275,7 +1334,7 @@ static void library_foreach_ID_link(Main *bmain,
Simulation *simulation = (Simulation *)id;
if (simulation->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- library_foreach_ID_as_subdata_link((ID **)&simulation->nodetree, &data);
+ BKE_library_foreach_ID_embedded(&data, (ID **)&simulation->nodetree);
}
break;
}