diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2017-05-05 17:13:01 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2017-05-05 17:19:16 +0300 |
commit | 198248fa3d3530e8d84967c7fa8a8d3b1a1c8214 (patch) | |
tree | 3b0461e78947c3356f59c890524daa1522e3572f | |
parent | 294ffa0d493c9a3f232355941cdb2dfe0da7706e (diff) |
Add a new LOOPBACK flag to libquery's callbacks.
That one tags those ugly little 'from' ID pointers (shape keys and
proxies), which point back from used to user ID, and require a lot of
special care in data-block management...
-rw-r--r-- | source/blender/blenkernel/BKE_library_query.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 21 |
2 files changed, 11 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h index 68bf9f43fe1..6cf18e28e17 100644 --- a/source/blender/blenkernel/BKE_library_query.h +++ b/source/blender/blenkernel/BKE_library_query.h @@ -51,6 +51,11 @@ enum { * This means callback shall not *do* anything, only use this as informative data if it needs it. */ IDWALK_CB_PRIVATE = (1 << 3), + /** That ID is not really used by its owner, it's just an internal hint/helper. + * This addresses Their Highest Ugliness the 'from' pointers: Object->from_proxy and Key->from. + * How to handle that kind of cases totally depends on what caller code is doing... */ + IDWALK_CB_LOOPBACK = (1 << 4), + /** * Adjusts #ID.us reference-count. * \note keep in sync with 'newlibadr_us' use in readfile.c diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 3d65fa9b6e1..931002e6bbc 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -540,7 +540,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call if (object->proxy_from) { data.cb_flag = ID_IS_LINKED_DATABLOCK(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0; } - CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_NOP); + CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_LOOPBACK); data.cb_flag = data_cb_flag; CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER); @@ -745,12 +745,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_KE: { - /* XXX Only ID pointer from shapekeys is the 'from' one, which is not actually ID usage. - * Maybe we should even nuke it from here, not 100% sure yet... - * (see also foreach_libblock_id_users_callback). - */ Key *key = (Key *) id; - CALLBACK_INVOKE_ID(key->from, IDWALK_CB_NOP); + CALLBACK_INVOKE_ID(key->from, IDWALK_CB_LOOPBACK); break; } @@ -1146,20 +1142,15 @@ typedef struct IDUsersIter { int count_direct, count_indirect; /* Set by callback. */ } IDUsersIter; -static int foreach_libblock_id_users_callback(void *user_data, ID *self_id, ID **id_p, int cb_flag) +static int foreach_libblock_id_users_callback(void *user_data, ID *UNUSED(self_id), ID **id_p, int cb_flag) { IDUsersIter *iter = user_data; if (*id_p) { - /* XXX This is actually some kind of hack... - * Issue is, shapekeys' 'from' ID pointer is not actually ID usage. - * Maybe we should even nuke it from BKE_library_foreach_ID_link, not 100% sure yet... + /* 'Loopback' ID pointers (the ugly 'from' ones, Object->proxy_from and Key->from). + * Those are not actually ID usage, we can ignore them here. */ - if ((GS(self_id->name) == ID_KE) && (((Key *)self_id)->from == *id_p)) { - return IDWALK_RET_NOP; - } - /* XXX another hack, for similar reasons as above one. */ - if ((GS(self_id->name) == ID_OB) && (((Object *)self_id)->proxy_from == (Object *)*id_p)) { + if (cb_flag & IDWALK_CB_LOOPBACK) { return IDWALK_RET_NOP; } |