Rework library_query foreach looper - add optional recursivity.

This commit:
* Fixes bad handling of 'stop iteration' (by adding a status flag, so that we can actually
  stop in helper functions too, and jumping to a finalize label instead of raw return, to
  allow propper clean up).
* Adds optional recursion into 'ID tree' - callback can also decide to exclude current id_pp
  from recursion. Note that this implies 'readonly', modifying IDs while recursing is not
  something we want to support!
* Changes callback signature/expected behavior: return behavior is now handled through flags,
  and 'parent' ID of id_pp is also passed (since it may not always be root id anymore).

Reviewers: sergey, campbellbarton

Differential Revision: https://developer.blender.org/D1869
This commit is contained in:
Bastien Montagne 2016-03-24 12:28:41 +01:00
parent 60cf62ff4b
commit c08924bf94
Notes: blender-bot 2023-12-22 20:14:11 +01:00
Referenced by commit 6483c3c280, Fix own regression in rBc08924bf94f2dff - foreach ID looper was broken due to missing initialization.
6 changed files with 530 additions and 457 deletions

View File

@ -50,15 +50,23 @@ enum {
IDWALK_USER_ONE = (1 << 9),
};
/* Call a callback for each ID link which the given ID uses.
enum {
IDWALK_RET_NOP = 0,
IDWALK_RET_STOP_ITER = 1 << 0, /* Completly top iteration. */
IDWALK_RET_STOP_RECURSION = 1 << 1, /* Stop recursion, that is, do not loop over ID used by current one. */
};
/**
* Call a callback for each ID link which the given ID uses.
*
* Return 'false' if you want to stop iteration.
* \return a set of flags to controll further iteration (0 to keep going).
*/
typedef bool (*LibraryIDLinkCallback) (void *user_data, struct ID **id_pointer, int cd_flag);
typedef int (*LibraryIDLinkCallback) (void *user_data, struct ID *id_self, struct ID **id_pointer, int cd_flag);
/* Flags for the foreach function itself. */
enum {
IDWALK_READONLY = (1 << 0),
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
};
/* Loop over all of the ID's this datablock links to. */

View File

@ -1086,7 +1086,7 @@ void *BKE_libblock_copy(ID *id)
return BKE_libblock_copy_ex(G.main, id);
}
static bool id_relink_looper(void *UNUSED(user_data), ID **id_pointer, const int cd_flag)
static int id_relink_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag)
{
ID *id = *id_pointer;
if (id) {
@ -1100,7 +1100,7 @@ static bool id_relink_looper(void *UNUSED(user_data), ID **id_pointer, const int
BKE_libblock_relink(id);
}
}
return true;
return IDWALK_RET_NOP;
}
void BKE_libblock_relink(ID *id)

File diff suppressed because it is too large Load Diff

View File

@ -2123,12 +2123,14 @@ enum {
MAKE_LOCAL_ALL = 4,
};
static bool tag_localizable_looper(void *UNUSED(user_data), ID **id_pointer, const int UNUSED(cd_flag))
static int tag_localizable_looper(
void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int UNUSED(cd_flag))
{
if (*id_pointer) {
(*id_pointer)->tag &= ~LIB_TAG_DOIT;
}
return true;
return IDWALK_RET_NOP;
}
static void tag_localizable_objects(bContext *C, const int mode)

View File

@ -80,7 +80,8 @@ static bool id_check_type(const ID *id, const BLI_bitmap *types_bitmap)
return BLI_BITMAP_TEST_BOOL(types_bitmap, id_code_as_index(GS(id->name)));
}
static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, int UNUSED(cb_flag))
static int foreach_libblock_id_user_map_callback(
void *user_data, ID *UNUSED(self_id), ID **id_p, int UNUSED(cb_flag))
{
IDUserMapData *data = user_data;
@ -88,7 +89,7 @@ static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, in
if (data->types_bitmap) {
if (!id_check_type(*id_p, data->types_bitmap)) {
return true;
return IDWALK_RET_NOP;
}
}
@ -104,7 +105,7 @@ static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, in
/* limit to key's added already */
if (data->is_subset) {
return true;
return IDWALK_RET_NOP;
}
/* Cannot use our placeholder key here! */
@ -122,7 +123,7 @@ static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, in
PySet_Add(set, data->py_id_curr);
}
return true;
return IDWALK_RET_NOP;
}
PyDoc_STRVAR(bpy_user_map_doc,

View File

@ -4913,7 +4913,7 @@ static void previews_id_ensure(bContext *C, Scene *scene, ID *id)
}
}
static bool previews_id_ensure_callback(void *todo_v, ID **idptr, int UNUSED(cd_flag))
static int previews_id_ensure_callback(void *todo_v, ID *UNUSED(idself), ID **idptr, int UNUSED(cd_flag))
{
PreviewsIDEnsureStack *todo = todo_v;
ID *id = *idptr;
@ -4926,7 +4926,7 @@ static bool previews_id_ensure_callback(void *todo_v, ID **idptr, int UNUSED(cd_
BLI_LINKSTACK_PUSH(todo->id_stack, id);
}
return true;
return IDWALK_RET_NOP;
}
static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op))