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:
2016-03-24 12:28:41 +01:00
parent 60cf62ff4b
commit c08924bf94
6 changed files with 530 additions and 457 deletions

View File

@@ -50,15 +50,23 @@ enum {
IDWALK_USER_ONE = (1 << 9), 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. */ /* Flags for the foreach function itself. */
enum { enum {
IDWALK_READONLY = (1 << 0), IDWALK_READONLY = (1 << 0),
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
}; };
/* Loop over all of the ID's this datablock links to. */ /* 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); 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; ID *id = *id_pointer;
if (id) { if (id) {
@@ -1100,7 +1100,7 @@ static bool id_relink_looper(void *UNUSED(user_data), ID **id_pointer, const int
BKE_libblock_relink(id); BKE_libblock_relink(id);
} }
} }
return true; return IDWALK_RET_NOP;
} }
void BKE_libblock_relink(ID *id) 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, 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) { if (*id_pointer) {
(*id_pointer)->tag &= ~LIB_TAG_DOIT; (*id_pointer)->tag &= ~LIB_TAG_DOIT;
} }
return true;
return IDWALK_RET_NOP;
} }
static void tag_localizable_objects(bContext *C, const int mode) 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))); 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; 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 (data->types_bitmap) {
if (!id_check_type(*id_p, 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 */ /* limit to key's added already */
if (data->is_subset) { if (data->is_subset) {
return true; return IDWALK_RET_NOP;
} }
/* Cannot use our placeholder key here! */ /* 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); PySet_Add(set, data->py_id_curr);
} }
return true; return IDWALK_RET_NOP;
} }
PyDoc_STRVAR(bpy_user_map_doc, 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; PreviewsIDEnsureStack *todo = todo_v;
ID *id = *idptr; 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); BLI_LINKSTACK_PUSH(todo->id_stack, id);
} }
return true; return IDWALK_RET_NOP;
} }
static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op)) static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op))