Fix potential early-return in WM foreach_id process.
Add a function to check if iteration over ID usages should stop (using internal `IDWALK_STOP` status flag). Use it in `BKE_LIB_FOREACHID_PROCESS_` macros, and in `window_manager_foreach_id` to handle properly the active workspace case (previous code could skip the call to `BKE_workspace_active_set` in case iteration over ID usages was stopped by callback on that specific ID usage). Part of T90922: Fix return policy inconsistency in `scene_foreach_id`.
This commit is contained in:
parent
eae59645de
commit
51c1c1cd93
|
@ -143,6 +143,7 @@ enum {
|
|||
|
||||
typedef struct LibraryForeachIDData LibraryForeachIDData;
|
||||
|
||||
bool BKE_lib_query_foreachid_iter_stop(struct LibraryForeachIDData *data);
|
||||
bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
|
||||
struct ID **id_pp,
|
||||
int cb_flag);
|
||||
|
@ -154,7 +155,8 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
|
|||
#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))) { \
|
||||
BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag)); \
|
||||
if (BKE_lib_query_foreachid_iter_stop((_data))) { \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
@ -163,7 +165,8 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
|
|||
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
|
||||
{ \
|
||||
CHECK_TYPE(&((_id_super)->id), ID *); \
|
||||
if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
|
||||
BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
|
||||
if (BKE_lib_query_foreachid_iter_stop((_data))) { \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
|
|
@ -76,6 +76,13 @@ typedef struct LibraryForeachIDData {
|
|||
BLI_LINKSTACK_DECLARE(ids_todo, ID *);
|
||||
} LibraryForeachIDData;
|
||||
|
||||
/** Check whether current iteration over ID usages should be stopped or not.
|
||||
* \return true if the iteration should be stopped, false otherwise. */
|
||||
bool BKE_lib_query_foreachid_iter_stop(LibraryForeachIDData *data)
|
||||
{
|
||||
return (data->status & IDWALK_STOP) != 0;
|
||||
}
|
||||
|
||||
bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
|
||||
{
|
||||
if (!(data->status & IDWALK_STOP)) {
|
||||
|
|
|
@ -91,10 +91,14 @@ static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
/* This pointer can be NULL during old files reading, better be safe than sorry. */
|
||||
if (win->workspace_hook != NULL) {
|
||||
ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, workspace, IDWALK_CB_NOP);
|
||||
BKE_lib_query_foreachid_process(data, &workspace, IDWALK_CB_USER);
|
||||
/* Allow callback to set a different workspace. */
|
||||
BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
|
||||
if (BKE_lib_query_foreachid_iter_stop(data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
|
||||
BKE_screen_foreach_id_screen_area(data, area);
|
||||
|
|
Loading…
Reference in New Issue