Refactor: Move Editors' 'foreach_id' code into a new SpaceType callback.

Was a known pending TODO for quite some time already.

This commit should have no behavior change at all.
This commit is contained in:
Bastien Montagne
2023-08-17 14:42:04 +02:00
parent a80de9ed40
commit d7d487e13a
16 changed files with 309 additions and 231 deletions

View File

@@ -105,6 +105,13 @@ typedef struct SpaceType {
/* Used when we want to replace an ID by another (or NULL). */
void (*id_remap)(struct ScrArea *area, struct SpaceLink *sl, const struct IDRemapper *mappings);
/**
* foreach_id callback to process all ID pointers of the editor. Used indirectly by lib_query's
* #BKE_library_foreach_ID_link when #IDWALK_INCLUDE_UI bitflag is set (through WM's foreach_id
* usage of #BKE_screen_foreach_id_screen_area).
*/
void (*foreach_id)(struct SpaceLink *space_link, struct LibraryForeachIDData *data);
int (*space_subtype_get)(struct ScrArea *area);
void (*space_subtype_set)(struct ScrArea *area, int value);
void (*space_subtype_item_extend)(struct bContext *C, EnumPropertyItem **item, int *totitem);

View File

@@ -81,243 +81,15 @@ static void screen_free_data(ID *id)
MEM_SAFE_FREE(screen->tool_tip);
}
static void screen_foreach_id_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
{
if (ads != nullptr) {
BKE_LIB_FOREACHID_PROCESS_ID(data, ads->source, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, ads->filter_grp, IDWALK_CB_NOP);
}
}
void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area)
{
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, area->full, IDWALK_CB_NOP);
/* TODO: this should be moved to a callback in `SpaceType`, defined in each editor's own code.
* Will be for a later round of cleanup though... */
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
switch (sl->spacetype) {
case SPACE_VIEW3D: {
View3D *v3d = (View3D *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->camera, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->ob_center, IDWALK_CB_NOP);
if (v3d->localvd) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
}
BKE_viewer_path_foreach_id(data, &v3d->viewer_path);
break;
}
case SPACE_GRAPH: {
SpaceGraph *sipo = (SpaceGraph *)sl;
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
screen_foreach_id_dopesheet(data, sipo->ads));
SpaceType *space_type = BKE_spacetype_from_id(sl->spacetype);
if (!is_readonly) {
/* Force recalc of list of channels (i.e. including calculating F-Curve colors) to
* prevent the "black curves" problem post-undo. */
sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
}
break;
}
case SPACE_PROPERTIES: {
SpaceProperties *sbuts = (SpaceProperties *)sl;
BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
if (!is_readonly) {
if (sbuts->pinid == nullptr) {
sbuts->flag &= ~SB_PIN_CONTEXT;
}
/* NOTE: Restoring path pointers is complicated, if not impossible, because this contains
* data pointers too, not just ID ones. See #40046. */
MEM_SAFE_FREE(sbuts->path);
}
break;
}
case SPACE_FILE: {
if (!is_readonly) {
SpaceFile *sfile = (SpaceFile *)sl;
sfile->op = nullptr;
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
}
break;
}
case SPACE_ACTION: {
SpaceAction *saction = (SpaceAction *)sl;
screen_foreach_id_dopesheet(data, &saction->ads);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, saction->action, IDWALK_CB_NOP);
if (!is_readonly) {
/* Force recalc of list of channels, potentially updating the active action while we're
* at it (as it can only be updated that way) #28962. */
saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
}
break;
}
case SPACE_IMAGE: {
SpaceImage *sima = (SpaceImage *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->image, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->iuser.scene, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->gpd, IDWALK_CB_USER);
if (!is_readonly) {
sima->scopes.ok = 0;
}
break;
}
case SPACE_SEQ: {
SpaceSeq *sseq = (SpaceSeq *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sseq->gpd, IDWALK_CB_USER);
break;
}
case SPACE_NLA: {
SpaceNla *snla = (SpaceNla *)sl;
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
screen_foreach_id_dopesheet(data, snla->ads));
break;
}
case SPACE_TEXT: {
SpaceText *st = (SpaceText *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_USER_ONE);
break;
}
case SPACE_SCRIPT: {
SpaceScript *scpt = (SpaceScript *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scpt->script, IDWALK_CB_NOP);
break;
}
case SPACE_OUTLINER: {
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
if (space_outliner->treestore != nullptr) {
TreeStoreElem *tselem;
BLI_mempool_iter iter;
BLI_mempool_iternew(space_outliner->treestore, &iter);
while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
if (TSE_IS_REAL_ID(tselem)) {
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_NOP;
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
}
else if (!is_readonly) {
tselem->id = nullptr;
}
}
if (!is_readonly) {
/* rebuild hash table, because it depends on ids too */
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
}
}
break;
}
case SPACE_NODE: {
SpaceNode *snode = (SpaceNode *)sl;
const bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access &&
ntreeFromID(snode->id) == snode->nodetree;
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
bNodeTreePath *path = static_cast<bNodeTreePath *>(snode->treepath.first);
BLI_assert(path == nullptr || path->nodetree == snode->nodetree);
if (is_embedded_nodetree) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
if (path != nullptr) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
}
/* Embedded ID pointers are not remapped (besides exceptions), ensure it still matches
* actual data. Note that `snode->id` was already processed (and therefore potentially
* remapped) above. */
if (!is_readonly) {
snode->nodetree = (snode->id == nullptr) ? nullptr : ntreeFromID(snode->id);
if (path != nullptr) {
path->nodetree = snode->nodetree;
}
}
}
else {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_USER_ONE);
if (path != nullptr) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
}
}
/* Both `snode->id` and `snode->nodetree` have been remapped now, so their data can be
* accessed. */
BLI_assert(snode->id == nullptr || snode->nodetree == nullptr ||
(snode->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0 ||
snode->nodetree == ntreeFromID(snode->id));
if (path != nullptr) {
for (path = path->next; path != nullptr; path = path->next) {
BLI_assert(path->nodetree != nullptr);
if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0) {
BLI_assert((path->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0);
}
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
if (path->nodetree == nullptr) {
BLI_assert(!is_readonly);
/* Remaining path entries are invalid, remove them. */
for (bNodeTreePath *path_next; path; path = path_next) {
path_next = path->next;
BLI_remlink(&snode->treepath, path);
MEM_freeN(path);
}
break;
}
}
}
BLI_assert(path == nullptr);
if (!is_readonly) {
/* `edittree` is just the last in the path, set this directly since the path may have
* been shortened above. */
if (snode->treepath.last != nullptr) {
path = static_cast<bNodeTreePath *>(snode->treepath.last);
snode->edittree = path->nodetree;
}
else {
snode->edittree = nullptr;
}
}
else {
/* Only process this pointer in readonly case, otherwise could lead to a bad
* double-remapping e.g. */
if (is_embedded_nodetree && snode->edittree == snode->nodetree) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
data, snode->edittree, IDWALK_CB_EMBEDDED_NOT_OWNING);
}
else {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_NOP);
}
}
break;
}
case SPACE_CLIP: {
SpaceClip *sclip = (SpaceClip *)sl;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->clip, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
if (!is_readonly) {
sclip->scopes.ok = 0;
}
break;
}
case SPACE_SPREADSHEET: {
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
BKE_viewer_path_foreach_id(data, &sspreadsheet->viewer_path);
break;
}
default:
break;
if (space_type && space_type->foreach_id) {
space_type->foreach_id(sl, data);
}
}
}

View File

@@ -21,6 +21,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_nla.h"
#include "BKE_screen.h"
@@ -805,6 +806,25 @@ static void action_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapp
BKE_id_remapper_apply(mappings, &sact->ads.source, ID_REMAP_APPLY_DEFAULT);
}
static void action_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceAction *sact = reinterpret_cast<SpaceAction *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sact->action, IDWALK_CB_NOP);
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceNla and #SpaceGraph. */
BKE_LIB_FOREACHID_PROCESS_ID(data, sact->ads.source, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sact->ads.filter_grp, IDWALK_CB_NOP);
if (!is_readonly) {
/* Force recalc of list of channels, potentially updating the active action while we're
* at it (as it can only be updated that way) #28962. */
sact->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
}
}
/**
* \note Used for splitting out a subset of modes is more involved,
* The previous non-timeline mode is stored so switching back to the
@@ -884,6 +904,7 @@ void ED_spacetype_action()
st->listener = action_listener;
st->refresh = action_refresh;
st->id_remap = action_id_remap;
st->foreach_id = action_foreach_id;
st->space_subtype_item_extend = action_space_subtype_item_extend;
st->space_subtype_get = action_space_subtype_get;
st->space_subtype_set = action_space_subtype_set;

View File

@@ -17,6 +17,7 @@
#include "BKE_context.h"
#include "BKE_gpencil_modifier_legacy.h" /* Types for registering panels. */
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
@@ -906,6 +907,23 @@ static void buttons_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemap
}
}
static void buttons_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceProperties *sbuts = reinterpret_cast<SpaceProperties *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
if (!is_readonly) {
if (sbuts->pinid == nullptr) {
sbuts->flag &= ~SB_PIN_CONTEXT;
}
/* NOTE: Restoring path pointers is complicated, if not impossible, because this contains
* data pointers too, not just ID ones. See #40046. */
MEM_SAFE_FREE(sbuts->path);
}
}
static void buttons_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
{
SpaceProperties *sbuts = (SpaceProperties *)sl;
@@ -954,6 +972,7 @@ void ED_spacetype_buttons()
st->listener = buttons_area_listener;
st->context = buttons_context;
st->id_remap = buttons_id_remap;
st->foreach_id = buttons_foreach_id;
st->blend_read_data = buttons_space_blend_read_data;
st->blend_read_lib = buttons_space_blend_read_lib;
st->blend_write = buttons_space_blend_write;

View File

@@ -23,6 +23,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_movieclip.h"
#include "BKE_screen.h"
@@ -1162,6 +1163,20 @@ static void clip_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
BKE_id_remapper_apply(mappings, (ID **)&sclip->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
}
static void clip_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceClip *sclip = reinterpret_cast<SpaceClip *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->clip, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
if (!is_readonly) {
sclip->scopes.ok = 0;
}
}
static void clip_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
{
SpaceClip *sclip = (SpaceClip *)sl;
@@ -1209,6 +1224,7 @@ void ED_spacetype_clip()
st->dropboxes = clip_dropboxes;
st->refresh = clip_refresh;
st->id_remap = clip_id_remap;
st->foreach_id = clip_foreach_id;
st->blend_read_data = clip_space_blend_read_data;
st->blend_read_lib = clip_space_blend_read_lib;
st->blend_write = clip_space_blend_write;

View File

@@ -18,6 +18,7 @@
#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -843,6 +844,20 @@ static void file_id_remap(ScrArea *area, SpaceLink *sl, const IDRemapper * /*map
file_reset_filelist_showing_main_data(area, sfile);
}
static void file_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceFile *sfile = reinterpret_cast<SpaceFile *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
/* TODO: investigate whether differences between this code and the one in #file_id_remap are
* meaningful and make sense or not. */
if (!is_readonly) {
sfile->op = nullptr;
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
}
}
static void file_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
{
SpaceFile *sfile = (SpaceFile *)sl;
@@ -912,6 +927,7 @@ void ED_spacetype_file()
st->space_subtype_set = file_space_subtype_set;
st->context = file_context;
st->id_remap = file_id_remap;
st->foreach_id = file_foreach_id;
st->blend_read_data = file_space_blend_read_data;
st->blend_read_lib = file_space_blend_read_lib;
st->blend_write = file_space_blend_write;

View File

@@ -21,6 +21,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_screen.h"
@@ -814,6 +815,27 @@ static void graph_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemappe
BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->source, ID_REMAP_APPLY_DEFAULT);
}
static void graph_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceGraph *sgraph = reinterpret_cast<SpaceGraph *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceAction and #SpaceNla. */
if (sgraph->ads == nullptr) {
return;
}
BKE_LIB_FOREACHID_PROCESS_ID(data, sgraph->ads->source, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sgraph->ads->filter_grp, IDWALK_CB_NOP);
if (!is_readonly) {
/* Force recalc of list of channels (i.e. including calculating F-Curve colors) to
* prevent the "black curves" problem post-undo. */
sgraph->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
}
}
static int graph_space_subtype_get(ScrArea *area)
{
SpaceGraph *sgraph = static_cast<SpaceGraph *>(area->spacedata.first);
@@ -886,6 +908,7 @@ void ED_spacetype_ipo()
st->listener = graph_listener;
st->refresh = graph_refresh;
st->id_remap = graph_id_remap;
st->foreach_id = graph_foreach_id;
st->space_subtype_item_extend = graph_space_subtype_item_extend;
st->space_subtype_get = graph_space_subtype_get;
st->space_subtype_set = graph_space_subtype_set;

View File

@@ -23,6 +23,7 @@
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_screen.h"
@@ -1003,6 +1004,21 @@ static void image_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemappe
BKE_id_remapper_apply(mappings, (ID **)&simg->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
}
static void image_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceImage *simg = reinterpret_cast<SpaceImage *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->image, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->iuser.scene, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->mask_info.mask, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->gpd, IDWALK_CB_USER);
if (!is_readonly) {
simg->scopes.ok = 0;
}
}
/**
* \note Used for splitting out a subset of modes is more involved,
* The previous non-uv-edit mode is stored so switching back to the
@@ -1097,6 +1113,7 @@ void ED_spacetype_image()
st->context = image_context;
st->gizmos = image_widgets;
st->id_remap = image_id_remap;
st->foreach_id = image_foreach_id;
st->space_subtype_item_extend = image_space_subtype_item_extend;
st->space_subtype_get = image_space_subtype_get;
st->space_subtype_set = image_space_subtype_set;

View File

@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_screen.h"
@@ -570,6 +571,19 @@ static void nla_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
mappings, reinterpret_cast<ID **>(&snla->ads->source), ID_REMAP_APPLY_DEFAULT);
}
static void nla_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceNla *snla = reinterpret_cast<SpaceNla *>(space_link);
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceAction and #SpaceGraph. */
if (snla->ads == nullptr) {
return;
}
BKE_LIB_FOREACHID_PROCESS_ID(data, snla->ads->source, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snla->ads->filter_grp, IDWALK_CB_NOP);
}
static void nla_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
{
SpaceNla *snla = reinterpret_cast<SpaceNla *>(sl);
@@ -613,6 +627,7 @@ void ED_spacetype_nla()
st->listener = nla_listener;
st->keymap = nla_keymap;
st->id_remap = nla_id_remap;
st->foreach_id = nla_foreach_id;
st->blend_read_data = nla_space_blend_read_data;
st->blend_read_lib = nla_space_blend_read_lib;
st->blend_write = nla_space_blend_write;

View File

@@ -18,6 +18,7 @@
#include "BKE_context.h"
#include "BKE_gpencil_legacy.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
@@ -1029,6 +1030,96 @@ static void node_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
BKE_id_remapper_iter(mappings, node_id_remap_cb, slink);
}
static void node_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceNode *snode = reinterpret_cast<SpaceNode *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
const bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access &&
ntreeFromID(snode->id) == snode->nodetree;
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
bNodeTreePath *path = static_cast<bNodeTreePath *>(snode->treepath.first);
BLI_assert(path == nullptr || path->nodetree == snode->nodetree);
if (is_embedded_nodetree) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
if (path != nullptr) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
}
/* Embedded ID pointers are not remapped (besides exceptions), ensure it still matches
* actual data. Note that `snode->id` was already processed (and therefore potentially
* remapped) above. */
if (!is_readonly) {
snode->nodetree = (snode->id == nullptr) ? nullptr : ntreeFromID(snode->id);
if (path != nullptr) {
path->nodetree = snode->nodetree;
}
}
}
else {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_USER_ONE);
if (path != nullptr) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
}
}
/* Both `snode->id` and `snode->nodetree` have been remapped now, so their data can be
* accessed. */
BLI_assert(snode->id == nullptr || snode->nodetree == nullptr ||
(snode->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0 ||
snode->nodetree == ntreeFromID(snode->id));
if (path != nullptr) {
for (path = path->next; path != nullptr; path = path->next) {
BLI_assert(path->nodetree != nullptr);
if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0) {
BLI_assert((path->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0);
}
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
if (path->nodetree == nullptr) {
BLI_assert(!is_readonly);
/* Remaining path entries are invalid, remove them. */
for (bNodeTreePath *path_next; path; path = path_next) {
path_next = path->next;
BLI_remlink(&snode->treepath, path);
MEM_freeN(path);
}
break;
}
}
}
BLI_assert(path == nullptr);
if (!is_readonly) {
/* `edittree` is just the last in the path, set this directly since the path may have
* been shortened above. */
if (snode->treepath.last != nullptr) {
path = static_cast<bNodeTreePath *>(snode->treepath.last);
snode->edittree = path->nodetree;
}
else {
snode->edittree = nullptr;
}
}
else {
/* Only process this pointer in readonly case, otherwise could lead to a bad
* double-remapping e.g. */
if (is_embedded_nodetree && snode->edittree == snode->nodetree) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_EMBEDDED_NOT_OWNING);
}
else {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_NOP);
}
}
}
static int node_space_subtype_get(ScrArea *area)
{
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
@@ -1151,6 +1242,7 @@ void ED_spacetype_node()
st->dropboxes = node_dropboxes;
st->gizmos = node_widgets;
st->id_remap = node_id_remap;
st->foreach_id = node_foreach_id;
st->space_subtype_item_extend = node_space_subtype_item_extend;
st->space_subtype_get = node_space_subtype_get;
st->space_subtype_set = node_space_subtype_set;

View File

@@ -19,6 +19,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_outliner_treehash.hh"
#include "BKE_screen.h"
@@ -441,6 +442,38 @@ static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const IDRemapper
}
}
static void outliner_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(space_link);
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
if (space_outliner->treestore != nullptr) {
TreeStoreElem *tselem;
BLI_mempool_iter iter;
BLI_mempool_iternew(space_outliner->treestore, &iter);
while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
if (TSE_IS_REAL_ID(tselem)) {
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_NOP;
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
}
else if (!is_readonly) {
tselem->id = nullptr;
}
}
if (!is_readonly) {
/* rebuild hash table, because it depends on ids too */
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
}
}
}
static void outliner_deactivate(ScrArea *area)
{
/* Remove hover highlights */
@@ -583,6 +616,7 @@ void ED_spacetype_outliner()
st->keymap = outliner_keymap;
st->dropboxes = outliner_dropboxes;
st->id_remap = outliner_id_remap;
st->foreach_id = outliner_foreach_id;
st->deactivate = outliner_deactivate;
st->context = outliner_context;
st->blend_read_data = outliner_space_blend_read_data;

View File

@@ -15,6 +15,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
#include "BKE_screen.h"
#include "ED_screen.hh"
@@ -147,6 +148,12 @@ static void script_main_region_listener(const wmRegionListenerParams * /*params*
#endif
}
static void script_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceScript *scpt = reinterpret_cast<SpaceScript *>(space_link);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scpt->script, IDWALK_CB_NOP);
}
static void script_space_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
{
SpaceScript *scpt = (SpaceScript *)sl;
@@ -180,6 +187,7 @@ void ED_spacetype_script()
st->duplicate = script_duplicate;
st->operatortypes = script_operatortypes;
st->keymap = script_keymap;
st->foreach_id = script_foreach_id;
st->blend_read_lib = script_space_blend_read_lib;
st->blend_write = script_space_blend_write;

View File

@@ -10,6 +10,7 @@
#include <cstdio>
#include <cstring>
#include "DNA_gpencil_legacy_types.h"
#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
@@ -20,6 +21,7 @@
#include "BLI_math_base.h"
#include "BKE_global.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "BKE_sequencer_offscreen.h"
@@ -925,6 +927,12 @@ static void sequencer_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRem
BKE_id_remapper_apply(mappings, (ID **)&sseq->gpd, ID_REMAP_APPLY_DEFAULT);
}
static void sequencer_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceSeq *sseq = reinterpret_cast<SpaceSeq *>(space_link);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sseq->gpd, IDWALK_CB_USER);
}
/* ************************************* */
static bool sequencer_channel_region_poll(const RegionPollParams *params)
@@ -1012,6 +1020,7 @@ void ED_spacetype_sequencer()
st->refresh = sequencer_refresh;
st->listener = sequencer_listener;
st->id_remap = sequencer_id_remap;
st->foreach_id = sequencer_foreach_id;
st->blend_read_data = sequencer_space_blend_read_data;
st->blend_read_lib = sequencer_space_blend_read_lib;
st->blend_write = sequencer_space_blend_write;

View File

@@ -163,6 +163,12 @@ static void spreadsheet_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDR
BKE_viewer_path_id_remap(&sspreadsheet->viewer_path, mappings);
}
static void spreadsheet_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceSpreadsheet *sspreadsheet = reinterpret_cast<SpaceSpreadsheet *>(space_link);
BKE_viewer_path_foreach_id(data, &sspreadsheet->viewer_path);
}
static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
{
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM | V2D_SCROLL_VERTICAL_HIDE |
@@ -721,6 +727,7 @@ void ED_spacetype_spreadsheet()
st->operatortypes = spreadsheet_operatortypes;
st->keymap = spreadsheet_keymap;
st->id_remap = spreadsheet_id_remap;
st->foreach_id = spreadsheet_foreach_id;
st->blend_read_data = spreadsheet_blend_read_data;
st->blend_read_lib = spreadsheet_blend_read_lib;
st->blend_write = spreadsheet_blend_write;

View File

@@ -17,6 +17,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_screen.h"
@@ -396,6 +397,12 @@ static void text_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
BKE_id_remapper_apply(mappings, (ID **)&stext->text, ID_REMAP_APPLY_ENSURE_REAL);
}
static void text_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceText *st = reinterpret_cast<SpaceText *>(space_link);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_USER_ONE);
}
static void text_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
{
SpaceText *st = (SpaceText *)sl;
@@ -433,6 +440,7 @@ void ED_spacetype_text()
st->context = text_context;
st->dropboxes = text_dropboxes;
st->id_remap = text_id_remap;
st->foreach_id = text_foreach_id;
st->blend_read_data = text_space_blend_read_data;
st->blend_read_lib = text_space_blend_read_lib;
st->blend_write = text_space_blend_write;

View File

@@ -42,6 +42,7 @@
#include "BKE_lattice.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_mball.h"
@@ -2092,6 +2093,18 @@ static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const IDRemapper *m
BKE_viewer_path_id_remap(&view3d->viewer_path, mappings);
}
static void view3d_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
View3D *v3d = reinterpret_cast<View3D *>(space_link);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->camera, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->ob_center, IDWALK_CB_NOP);
if (v3d->localvd) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
}
BKE_viewer_path_foreach_id(data, &v3d->viewer_path);
}
static void view3d_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
{
View3D *v3d = (View3D *)sl;
@@ -2166,6 +2179,7 @@ void ED_spacetype_view3d()
st->gizmos = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
st->foreach_id = view3d_foreach_id;
st->blend_read_data = view3d_space_blend_read_data;
st->blend_read_lib = view3d_space_blend_read_lib;
st->blend_write = view3d_space_blend_write;