From 63b7ff9f4e5f5b0ff5d6bdb726fcd4e1d118e141 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 4 Mar 2021 18:39:07 +0100 Subject: Cleanup: Main `foreach ID` code: Remove `MAX_LIBARRAY` and improve comments. The `MAX_LIBARRAY` define was an annoying doublon to the `INDEX_ID_MAX` enum value now defined in `DNA_ID.h`, and it is no more useful. And comments were somewhat outdated. Also added an explanation about chosen order for the `INDEX_ID_` order. --- source/blender/blenkernel/BKE_main.h | 16 ++++++---- source/blender/blenkernel/intern/blendfile.c | 2 +- source/blender/blenkernel/intern/bpath.c | 2 +- source/blender/blenkernel/intern/idtype.c | 2 +- source/blender/blenkernel/intern/lib_id.c | 6 ++-- source/blender/blenkernel/intern/lib_id_delete.c | 2 +- source/blender/blenkernel/intern/lib_query.c | 8 ++--- source/blender/blenkernel/intern/main.c | 23 +++++++-------- source/blender/blenkernel/intern/main_idmap.c | 10 +++---- source/blender/blenloader/intern/blend_validate.c | 2 +- source/blender/blenloader/intern/readfile.c | 22 +++++++------- source/blender/blenloader/intern/versioning_270.c | 2 +- source/blender/blenloader/intern/writefile.c | 4 +-- source/blender/depsgraph/intern/depsgraph.h | 8 ++--- .../space_outliner/tree/tree_display_libraries.cc | 2 +- .../space_outliner/tree/tree_display_orphaned.cc | 2 +- source/blender/makesdna/DNA_ID.h | 34 ++++++++++++++++++++-- source/blender/python/intern/bpy_library_load.c | 4 +-- .../blender/windowmanager/intern/wm_files_link.c | 2 +- 19 files changed, 92 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index b6116b32ca5..2c6e5ed3873 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -223,7 +223,7 @@ struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset); #define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb) \ { \ - ListBase *_lbarray[MAX_LIBARRAY]; \ + ListBase *_lbarray[INDEX_ID_MAX]; \ int _i = set_listbasepointers((_bmain), _lbarray); \ while (_i--) { \ (_lb) = _lbarray[_i]; @@ -234,9 +234,13 @@ struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset); ((void)0) /** - * DO NOT use break statement with that macro, - * use #FOREACH_MAIN_LISTBASE and #FOREACH_MAIN_LISTBASE_ID instead - * if you need that kind of control flow. */ + * Top level `foreach`-like macro allowing to loop over all IDs in a given #Main data-base. + * + * NOTE: Order tries to go from 'user IDs' to 'used IDs' (e.g. collections will be processed + * before objects, which will be processed before obdata types, etc.). + * + * WARNING: DO NOT use break statement with that macro, use #FOREACH_MAIN_LISTBASE and + * #FOREACH_MAIN_LISTBASE_ID instead if you need that kind of control flow. */ #define FOREACH_MAIN_ID_BEGIN(_bmain, _id) \ { \ ListBase *_lb; \ @@ -259,8 +263,8 @@ const char *BKE_main_blendfile_path_from_global(void); struct ListBase *which_libbase(struct Main *bmain, short type); -#define MAX_LIBARRAY 41 -int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]); +//#define INDEX_ID_MAX 41 +int set_listbasepointers(struct Main *main, struct ListBase *lb[]); #define MAIN_VERSION_ATLEAST(main, ver, subver) \ ((main)->versionfile > (ver) || \ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index 32710c4fa60..101f4b7caf6 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -865,7 +865,7 @@ bool BKE_blendfile_write_partial(Main *bmain_src, ReportList *reports) { Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer"); - ListBase *lbarray_dst[MAX_LIBARRAY], *lbarray_src[MAX_LIBARRAY]; + ListBase *lbarray_dst[INDEX_ID_MAX], *lbarray_src[INDEX_ID_MAX]; int a, retval; void *path_list_backup = NULL; diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 2ad0ac950d0..47427beccba 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -783,7 +783,7 @@ void BKE_bpath_traverse_main(Main *bmain, const int flag, void *bpath_user_data) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a = set_listbasepointers(bmain, lbarray); while (a--) { BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c index 1889d1c4eb0..fee70922570 100644 --- a/source/blender/blenkernel/intern/idtype.c +++ b/source/blender/blenkernel/intern/idtype.c @@ -63,7 +63,7 @@ bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v) (key_a->offset_in_ID != key_b->offset_in_ID) || (key_a->cache_v != key_b->cache_v); } -static IDTypeInfo *id_types[MAX_LIBARRAY] = {NULL}; +static IDTypeInfo *id_types[INDEX_ID_MAX] = {NULL}; static void id_type_init(void) { diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 54c2f5f5565..a511c1f9c4c 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -916,7 +916,7 @@ void BKE_main_id_tag_idcode(struct Main *mainvar, */ void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a; a = set_listbasepointers(mainvar, lbarray); @@ -949,7 +949,7 @@ void BKE_main_id_flag_listbase(ListBase *lb, const int flag, const bool value) */ void BKE_main_id_flag_all(Main *bmain, const int flag, const bool value) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a; a = set_listbasepointers(bmain, lbarray); while (a--) { @@ -1870,7 +1870,7 @@ void BKE_library_make_local(Main *bmain, const bool untagged_only, const bool set_fake) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; LinkNode *todo_ids = NULL; LinkNode *copied_ids = NULL; diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c index 7c5032c97f4..1d7f89e1e8d 100644 --- a/source/blender/blenkernel/intern/lib_id_delete.c +++ b/source/blender/blenkernel/intern/lib_id_delete.c @@ -240,7 +240,7 @@ void BKE_id_free_us(Main *bmain, void *idv) /* test users */ static size_t id_delete(Main *bmain, const bool do_tagged_deletion) { const int tag = LIB_TAG_DOIT; - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; Link dummy_link = {0}; int base_count, i; diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 796bc3dc3d0..acd0c10040c 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -440,7 +440,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) typedef struct IDUsersIter { ID *id; - ListBase *lb_array[MAX_LIBARRAY]; + ListBase *lb_array[INDEX_ID_MAX]; int lb_idx; ID *curr_id; @@ -514,7 +514,7 @@ int BKE_library_ID_use_ID(ID *id_user, ID *id_used) static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked) { IDUsersIter iter; - ListBase *lb_array[MAX_LIBARRAY]; + ListBase *lb_array[INDEX_ID_MAX]; ID *id = idv; int i = set_listbasepointers(bmain, lb_array); bool is_defined = false; @@ -567,7 +567,7 @@ bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv) void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked) { IDUsersIter iter; - ListBase *lb_array[MAX_LIBARRAY]; + ListBase *lb_array[INDEX_ID_MAX]; ID *id = idv; int i = set_listbasepointers(bmain, lb_array); bool is_defined = false; @@ -805,7 +805,7 @@ void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag) */ void BKE_library_indirectly_used_data_tag_clear(Main *bmain) { - ListBase *lb_array[MAX_LIBARRAY]; + ListBase *lb_array[INDEX_ID_MAX]; bool do_loop = true; while (do_loop) { diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c index 6f94b3355fa..ead1c5bf721 100644 --- a/source/blender/blenkernel/intern/main.c +++ b/source/blender/blenkernel/intern/main.c @@ -53,7 +53,7 @@ Main *BKE_main_new(void) void BKE_main_free(Main *mainvar) { /* also call when reading a file, erase all, etc */ - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a; /* Since we are removing whole main, no need to bother 'properly' @@ -532,18 +532,17 @@ ListBase *which_libbase(Main *bmain, short type) } /** - * puts into array *lb pointers to all the #ListBase structs in main, - * and returns the number of them as the function result. This is useful for - * generic traversal of all the blocks in a Main (by traversing all the - * lists in turn), without worrying about block types. + * Put the pointers to all the #ListBase structs in given `bmain` into the `*lb[INDEX_ID_MAX]` + * array, and return the number of those for convinience. * - * \note #MAX_LIBARRAY define should match this code */ -int set_listbasepointers(Main *bmain, ListBase **lb) + * This is useful for generic traversal of all the blocks in a #Main (by traversing all the lists + * in turn), without worrying about block types. + * + * \note The order of each ID type #ListBase in the array is determined by the `INDEX_ID_` + * enum definitions in `DNA_ID.h`. See also the #FOREACH_MAIN_ID_BEGIN macro in `BKE_main.h` + */ +int set_listbasepointers(Main *bmain, ListBase *lb[INDEX_ID_MAX]) { - /* BACKWARDS! also watch order of free-ing! (mesh<->mat), first items freed last. - * This is important because freeing data decreases user-counts of other data-blocks, - * if this data is its self freed it can crash. */ - /* Libraries may be accessed from pretty much any other ID. */ lb[INDEX_ID_LI] = &(bmain->libraries); @@ -606,5 +605,5 @@ int set_listbasepointers(Main *bmain, ListBase **lb) lb[INDEX_ID_NULL] = NULL; - return (MAX_LIBARRAY - 1); + return (INDEX_ID_MAX - 1); } diff --git a/source/blender/blenkernel/intern/main_idmap.c b/source/blender/blenkernel/intern/main_idmap.c index 21f5e9c6fb2..1d362db4432 100644 --- a/source/blender/blenkernel/intern/main_idmap.c +++ b/source/blender/blenkernel/intern/main_idmap.c @@ -66,7 +66,7 @@ struct IDNameLib_TypeMap { * Opaque structure, external API users only see this. */ struct IDNameLib_Map { - struct IDNameLib_TypeMap type_maps[MAX_LIBARRAY]; + struct IDNameLib_TypeMap type_maps[INDEX_ID_MAX]; struct GHash *uuid_map; struct Main *bmain; struct GSet *valid_id_pointers; @@ -77,7 +77,7 @@ static struct IDNameLib_TypeMap *main_idmap_from_idcode(struct IDNameLib_Map *id short id_type) { if (id_map->idmap_types & MAIN_IDMAP_TYPE_NAME) { - for (int i = 0; i < MAX_LIBARRAY; i++) { + for (int i = 0; i < INDEX_ID_MAX; i++) { if (id_map->type_maps[i].id_type == id_type) { return &id_map->type_maps[i]; } @@ -108,13 +108,13 @@ struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain, id_map->idmap_types = idmap_types; int index = 0; - while (index < MAX_LIBARRAY) { + while (index < INDEX_ID_MAX) { struct IDNameLib_TypeMap *type_map = &id_map->type_maps[index]; type_map->map = NULL; type_map->id_type = BKE_idtype_idcode_iter_step(&index); BLI_assert(type_map->id_type != 0); } - BLI_assert(index == MAX_LIBARRAY); + BLI_assert(index == INDEX_ID_MAX); if (idmap_types & MAIN_IDMAP_TYPE_UUID) { ID *id; @@ -231,7 +231,7 @@ void BKE_main_idmap_destroy(struct IDNameLib_Map *id_map) { if (id_map->idmap_types & MAIN_IDMAP_TYPE_NAME) { struct IDNameLib_TypeMap *type_map = id_map->type_maps; - for (int i = 0; i < MAX_LIBARRAY; i++, type_map++) { + for (int i = 0; i < INDEX_ID_MAX; i++, type_map++) { if (type_map->map) { BLI_ghash_free(type_map->map, NULL, NULL); type_map->map = NULL; diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c index 7261db5d3a6..f3fc1453461 100644 --- a/source/blender/blenloader/intern/blend_validate.c +++ b/source/blender/blenloader/intern/blend_validate.c @@ -60,7 +60,7 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports) blo_split_main(&mainlist, bmain); - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int i = set_listbasepointers(bmain, lbarray); while (i--) { for (ID *id = lbarray[i]->first; id != NULL; id = id->next) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c0293c1f8f2..2200f7c291b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -449,7 +449,7 @@ static void oldnewmap_free(OldNewMap *onm) static void add_main_to_main(Main *mainvar, Main *from) { - ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX], *fromarray[INDEX_ID_MAX]; int a; set_listbasepointers(mainvar, lbarray); @@ -517,7 +517,7 @@ void blo_split_main(ListBase *mainlist, Main *main) lib_main_array[i] = libmain; } - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; i = set_listbasepointers(main, lbarray); while (i--) { ID *id = lbarray[i]->first; @@ -1965,7 +1965,7 @@ void blo_end_packed_pointer_map(FileData *fd, Main *oldmain) /* undo file support: add all library pointers in lookup */ void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; LISTBASE_FOREACH (Main *, ptr, old_mainlist) { int i = set_listbasepointers(ptr, lbarray); @@ -4543,7 +4543,7 @@ void BLO_main_expander(BLOExpandDoitCallback expand_doit_func) */ void BLO_expand_main(void *fdhandle, Main *mainvar) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; FileData *fd = fdhandle; ID *id; int a; @@ -4713,7 +4713,7 @@ static void add_loose_object_data_to_scene(Main *mainvar, } /* Loop over all ID types, instancing object-data for ID types that have support for it. */ - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int i = set_listbasepointers(mainvar, lbarray); while (i--) { const short idcode = BKE_idtype_idcode_from_index(i); @@ -4979,7 +4979,7 @@ static bool library_link_idcode_needs_tag_check(const short idcode, const int fl */ static void library_link_clear_tag(Main *mainvar, const int flag) { - for (int i = 0; i < MAX_LIBARRAY; i++) { + for (int i = 0; i < INDEX_ID_MAX; i++) { const short idcode = BKE_idtype_idcode_from_index(i); BLI_assert(idcode != -1); if (library_link_idcode_needs_tag_check(idcode, flag)) { @@ -5068,8 +5068,8 @@ static void split_main_newid(Main *mainptr, Main *main_newid) BLI_strncpy(main_newid->name, mainptr->name, sizeof(main_newid->name)); main_newid->curlib = mainptr->curlib; - ListBase *lbarray[MAX_LIBARRAY]; - ListBase *lbarray_newid[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; + ListBase *lbarray_newid[INDEX_ID_MAX]; int i = set_listbasepointers(mainptr, lbarray); set_listbasepointers(main_newid, lbarray_newid); while (i--) { @@ -5227,7 +5227,7 @@ void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname) static int has_linked_ids_to_read(Main *mainvar) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a = set_listbasepointers(mainvar, lbarray); while (a--) { @@ -5295,7 +5295,7 @@ static void read_library_linked_ids(FileData *basefd, { GHash *loaded_ids = BLI_ghash_str_new(__func__); - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a = set_listbasepointers(mainvar, lbarray); while (a--) { @@ -5344,7 +5344,7 @@ static void read_library_clear_weak_links(FileData *basefd, ListBase *mainlist, { /* Any remaining weak links at this point have been lost, silently drop * those by setting them to NULL pointers. */ - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a = set_listbasepointers(mainvar, lbarray); while (a--) { diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index d86ddc5b646..289092f7f19 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1141,7 +1141,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } } if (!MAIN_VERSION_ATLEAST(bmain, 276, 5)) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a; /* Important to clear all non-persistent flags from older versions here, diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 0a4f2fde93f..6fbd4b77487 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -768,7 +768,7 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef) /* Keep it last of write_foodata functions. */ static void write_libraries(WriteData *wd, Main *main) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; ID *id; int a, tot; bool found_one; @@ -954,7 +954,7 @@ static bool write_file_handle(Main *mainvar, * if needed, without duplicating whole code. */ Main *bmain = mainvar; do { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int a = set_listbasepointers(bmain, lbarray); while (a--) { ID *id = lbarray[a]->first; diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 14c91834739..df8c8215d2f 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -33,9 +33,7 @@ #include "MEM_guardedalloc.h" -#include "DNA_ID.h" /* for ID_Type */ - -#include "BKE_main.h" /* for MAX_LIBARRAY */ +#include "DNA_ID.h" /* for ID_Type and INDEX_ID_MAX */ #include "BLI_threads.h" /* for SpinLock */ @@ -111,10 +109,10 @@ struct Depsgraph { bool need_update; /* Indicates which ID types were updated. */ - char id_type_updated[MAX_LIBARRAY]; + char id_type_updated[INDEX_ID_MAX]; /* Indicates type of IDs present in the depsgraph. */ - char id_type_exist[MAX_LIBARRAY]; + char id_type_exist[INDEX_ID_MAX]; /* Quick-Access Temp Data ............. */ diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc index cb5f42f08e1..a81ce11498a 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc @@ -111,7 +111,7 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, { const short filter_id_type = id_filter_get(); - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int tot; if (filter_id_type) { lbarray[0] = which_libbase(&mainvar, space_outliner_.filter_id_type); diff --git a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc index 0b17ea98831..559cb289f3f 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc @@ -42,7 +42,7 @@ TreeDisplayIDOrphans::TreeDisplayIDOrphans(SpaceOutliner &space_outliner) ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data) { ListBase tree = {nullptr}; - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; short filter_id_type = (space_outliner_.filter & SO_FILTER_ID_TYPE) ? space_outliner_.filter_id_type : 0; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 67e33366199..b985ba1ed5f 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -722,8 +722,36 @@ typedef enum IDRecalcFlag { FILTER_ID_TE | FILTER_ID_TXT | FILTER_ID_VF | FILTER_ID_WO | FILTER_ID_CF | FILTER_ID_WS | \ FILTER_ID_LP | FILTER_ID_HA | FILTER_ID_PT | FILTER_ID_VO | FILTER_ID_SIM) -/* IMPORTANT: this enum matches the order currently use in set_listbasepointers, - * keep them in sync! */ +/** + * This enum defines the index assigned to each type of IDs in the array returned by + * #set_listbasepointers, and by extension, controls the default order in which each ID type is + * processed during standard 'foreach' looping over all IDs of a #Main data-base. + * + * About Order: + * ------------ + * + * This is (losely) defined with a relationship order in mind, from lowest level (ID types using, + * referencing almost no other ID types) to highest level (ID types potentially using many other ID + * types). + * + * So e.g. it ensures that this dependency chain is respected: + * #Material <- #Mesh <- #Object <- #Collection <- #Scene + * + * Default order of processing of IDs in 'foreach' macros (#FOREACH_MAIN_ID_BEGIN and the like), + * built on top of #set_listbasepointers, is actually reversed compared to the order defined here, + * since processing usually needs to happen on users before it happens on used IDs (when freeing + * e.g.). + * + * DO NOT rely on this order as being full-proofed dependency order, there are many cases were it + * can be violated (most obvious cases being custom properties and drivers, which can reference any + * other ID types). + * + * However, this order can be considered as an optimization heuristic, especially when processing + * relationships in a non-recursive pattern: in typical cases, a vast majority of those + * relationships can be processed fine in the first pass, and only few additional passes are + * required to address all remaining relationship cases. + * See e.g. how #BKE_library_unused_linked_data_set_tag is doing this. + */ enum { INDEX_ID_LI = 0, INDEX_ID_IP, @@ -763,6 +791,8 @@ enum { INDEX_ID_SCE, INDEX_ID_WS, INDEX_ID_WM, + /* TODO: This should probably be tweaked, #Mask and #Simulation are rather low-level types that + * should most likely be defined //before// #Object and geometry type indices? */ INDEX_ID_MSK, INDEX_ID_SIM, INDEX_ID_NULL, diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 24eb9a61512..03771a8c294 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -217,7 +217,7 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0) | (use_assets_only ? FILE_ASSETS_ONLY : 0)); - ret->dict = _PyDict_NewPresized(MAX_LIBARRAY); + ret->dict = _PyDict_NewPresized(INDEX_ID_MAX); return (PyObject *)ret; } @@ -248,7 +248,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self) { PyObject *ret; BPy_Library *self_from; - PyObject *from_dict = _PyDict_NewPresized(MAX_LIBARRAY); + PyObject *from_dict = _PyDict_NewPresized(INDEX_ID_MAX); ReportList reports; BKE_reports_init(&reports, RPT_STORE); diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index d4495821672..6a1fc84774c 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -804,7 +804,7 @@ static void lib_relocate_do(Main *bmain, ReportList *reports, const bool do_reload) { - ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray[INDEX_ID_MAX]; int lba_idx; LinkNode *itemlink; -- cgit v1.2.3