diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-09-08 08:32:43 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-09-08 09:14:33 +0300 |
commit | e467c54d58c88316d959f2481dc7484037a4c0be (patch) | |
tree | 4cdf31ed7bac3efeef7f75075920cb23adfaee16 /source/blender | |
parent | 48690d967a7731367cda01ab8dca64e7f4c3f6b5 (diff) |
Refactor: move library linking arguments into a parameter struct
Move arguments to BLO_library_link_{begin/named_part/end} into
a single parameter struct, to ensure arguments always match.
This allows is to skip tagging ID's LIB_TAG_DOIT when it's not needed,
previously it was always cleared just in case it was needed.
This also makes it possible to remove BLO_library_link_named_part_ex
which was only used when tagging was needed.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/blender_copybuffer.c | 13 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 60 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 164 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_library_load.c | 9 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files_link.c | 10 |
5 files changed, 168 insertions, 88 deletions
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c index e950e94655a..9f5e038fb82 100644 --- a/source/blender/blenkernel/intern/blender_copybuffer.c +++ b/source/blender/blenkernel/intern/blender_copybuffer.c @@ -93,9 +93,12 @@ bool BKE_copybuffer_read(Main *bmain_dst, return false; } /* Here appending/linking starts. */ - Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname); + const int flag = 0; + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init(&liblink_params, bmain_dst, flag); + Main *mainl = BLO_library_link_begin(&bh, libname, &liblink_params); BLO_library_link_copypaste(mainl, bh, id_types_mask); - BLO_library_link_end(mainl, &bh, 0, NULL, NULL, NULL, NULL); + BLO_library_link_end(mainl, &bh, &liblink_params); /* Mark all library linked objects to be updated. */ BKE_main_lib_objects_recalc_all(bmain_dst); IMB_colormanagement_check_file_config(bmain_dst); @@ -144,11 +147,13 @@ int BKE_copybuffer_paste(bContext *C, BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &bh, libname); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init_with_context(&liblink_params, bmain, flag, scene, view_layer, v3d); + mainl = BLO_library_link_begin(&bh, libname, &liblink_params); const int num_pasted = BLO_library_link_copypaste(mainl, bh, id_types_mask); - BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d); + BLO_library_link_end(mainl, &bh, &liblink_params); /* mark all library linked objects to be updated */ BKE_main_lib_objects_recalc_all(bmain); diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index c9e837eb3b5..c83d8e037c8 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -138,6 +138,10 @@ void BLO_blendhandle_close(BlendHandle *bh); bool BLO_has_bfile_extension(const char *str); bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name); +/* -------------------------------------------------------------------- */ +/** \name BLO Blend File Linking API + * \{ */ + /* Options controlling behavior of append/link code. * Note: merged with 'user-level' options from operators etc. in 16 lower bits * (see eFileSel_Params_Flag in DNA_space_types.h). */ @@ -146,25 +150,63 @@ typedef enum BLO_LibLinkFlags { BLO_LIBLINK_USE_PLACEHOLDERS = 1 << 16, /* Force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). */ BLO_LIBLINK_FORCE_INDIRECT = 1 << 17, + /** + * When set, tag ID types that pass the internal check #library_link_idcode_needs_tag_check + * + * Currently this is only used to instantiate objects in the scene. + * Set this from #BLO_library_link_params_init_with_context so callers + * don't need to remember to set this flag. + */ + BLO_LIBLINK_NEEDS_ID_TAG_DOIT = 1 << 18, } BLO_LinkFlags; -struct Main *BLO_library_link_begin(struct Main *mainvar, BlendHandle **bh, const char *filepath); +/** + * Struct for passing arguments to + * #BLO_library_link_begin, #BLO_library_link_named_part & #BLO_library_link_end. + * Wrap these in parameters since it's important both functions receive matching values. + */ +struct LibraryLink_Params { + /** The current main database, e.g. #G_MAIN or `CTX_data_main(C)`. */ + struct Main *bmain; + /** Options for linking, used for instantiating. */ + int flag; + /** Context for instancing objects (optional, no instantiation will be performed when NULL). */ + struct { + /** The scene in which to instantiate objects/collections. */ + struct Scene *scene; + /** The scene layer in which to instantiate objects/collections. */ + struct ViewLayer *view_layer; + /** The active 3D viewport (only used to define local-view). */ + const struct View3D *v3d; + } context; +}; + +void BLO_library_link_params_init(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag); +void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag, + struct Scene *scene, + struct ViewLayer *view_layer, + const struct View3D *v3d); + +struct Main *BLO_library_link_begin(BlendHandle **bh, + const char *filepath, + const struct LibraryLink_Params *params); struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, const short idcode, - const char *name); -struct ID *BLO_library_link_named_part_ex( - struct Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag); + const char *name, + const struct LibraryLink_Params *params); void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, - int flag, - struct Main *bmain, - struct Scene *scene, - struct ViewLayer *view_layer, - const struct View3D *v3d); + const struct LibraryLink_Params *params); int BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh, const uint64_t id_types_mask); +/** \} */ + void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); /* internal function but we need to expose it */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 84cb898a426..35534963433 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -262,6 +262,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(BlendDataReader *reader, ListBase *lb, Object *ob); static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name); static BHead *find_bhead_from_idname(FileData *fd, const char *idname); +static bool library_link_idcode_needs_tag_check(const short idcode, const int flag); #ifdef USE_COLLECTION_COMPAT_28 static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc); @@ -10469,6 +10470,14 @@ static ID *link_named_part( /* if we found the id but the id is NULL, this is really bad */ BLI_assert(!((bhead != NULL) && (id == NULL))); + /* Tag as loose object (or data associated with objects) + * needing to be instantiated in #LibraryLink_Params.scene. */ + if ((id != NULL) && (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT)) { + if (library_link_idcode_needs_tag_check(idcode, flag)) { + id->tag |= LIB_TAG_DOIT; + } + } + return id; } @@ -10514,23 +10523,6 @@ int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const uint64_t id_t return num_directly_linked; } -static ID *link_named_part_ex( - Main *mainl, FileData *fd, const short idcode, const char *name, const int flag) -{ - ID *id = link_named_part(mainl, fd, idcode, name, flag); - - if (id && (GS(id->name) == ID_OB)) { - /* Tag as loose object needing to be instantiated somewhere... */ - id->tag |= LIB_TAG_DOIT; - } - else if (id && (GS(id->name) == ID_GR)) { - /* tag as needing to be instantiated or linked */ - id->tag |= LIB_TAG_DOIT; - } - - return id; -} - /** * Link a named data-block from an external blend file. * @@ -10543,41 +10535,53 @@ static ID *link_named_part_ex( ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcode, - const char *name) + const char *name, + const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - return link_named_part(mainl, fd, idcode, name, 0); + return link_named_part(mainl, fd, idcode, name, params->flag); } +/* common routine to append/link something from a library */ + /** - * Link a named data-block from an external blend file. - * Optionally instantiate the object/collection in the scene when the flags are set. - * - * \param mainl: The main database to link from (not the active one). - * \param bh: The blender file handle. - * \param idcode: The kind of data-block to link. - * \param name: The name of the data-block (without the 2 char ID prefix). - * \param flag: Options for linking, used for instantiating. - * \return the linked ID when found. + * Checks if the \a idcode needs to be tagged with #LIB_TAG_DOIT when linking/appending. */ -ID *BLO_library_link_named_part_ex( - Main *mainl, BlendHandle **bh, const short idcode, const char *name, const int flag) +static bool library_link_idcode_needs_tag_check(const short idcode, const int flag) { - FileData *fd = (FileData *)(*bh); - return link_named_part_ex(mainl, fd, idcode, name, flag); + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Always true because of #add_loose_objects_to_scene & #add_collections_to_scene. */ + if (ELEM(idcode, ID_OB, ID_GR)) { + return true; + } + } + return false; } -/* common routine to append/link something from a library */ +/** + * Clears #LIB_TAG_DOIT based on the result of #library_link_idcode_needs_tag_check. + */ +static void library_link_clear_tag(Main *mainvar, const int flag) +{ + for (int i = 0; i < MAX_LIBARRAY; i++) { + const short idcode = BKE_idtype_idcode_from_index(i); + BLI_assert(idcode != -1); + if (library_link_idcode_needs_tag_check(idcode, flag)) { + BKE_main_id_tag_idcode(mainvar, idcode, LIB_TAG_DOIT, false); + } + } +} -static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath) +static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath, const int flag) { Main *mainl; (*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist"); - /* clear for objects and collections instantiating tag */ - BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false); - BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false); + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Clear for objects and collections instantiating tag. */ + library_link_clear_tag(mainvar, flag); + } /* make mains */ blo_split_main((*fd)->mainlist, mainvar); @@ -10595,19 +10599,49 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa return mainl; } +void BLO_library_link_params_init(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag) +{ + memset(params, 0, sizeof(*params)); + params->bmain = bmain; + params->flag = flag; +} + +void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params, + struct Main *bmain, + const int flag, + /* Context arguments. */ + struct Scene *scene, + struct ViewLayer *view_layer, + const struct View3D *v3d) +{ + BLO_library_link_params_init(params, bmain, flag); + if (scene != NULL) { + /* Tagging is needed for instancing. */ + params->flag |= BLO_LIBLINK_NEEDS_ID_TAG_DOIT; + + params->context.scene = scene; + params->context.view_layer = view_layer; + params->context.v3d = v3d; + } +} + /** * Initialize the #BlendHandle for linking library data. * - * \param mainvar: The current main database, e.g. #G_MAIN or #CTX_data_main(C). * \param bh: A blender file handle as returned by * #BLO_blendhandle_from_file or #BLO_blendhandle_from_memory. * \param filepath: Used for relative linking, copied to the `lib->filepath`. - * \return the library #Main, to be passed to #BLO_library_link_named_part_ex as \a mainl. + * \param params: Settings for linking that don't change from beginning to end of linking. + * \return the library #Main, to be passed to #BLO_library_link_named_part as \a mainl. */ -Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepath) +Main *BLO_library_link_begin(BlendHandle **bh, + const char *filepath, + const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - return library_link_begin(mainvar, &fd, filepath); + return library_link_begin(params->bmain, &fd, filepath, params->flag); } static void split_main_newid(Main *mainptr, Main *main_newid) @@ -10642,8 +10676,8 @@ static void split_main_newid(Main *mainptr, Main *main_newid) */ static void library_link_end(Main *mainl, FileData **fd, - const short flag, Main *bmain, + const int flag, Scene *scene, ViewLayer *view_layer, const View3D *v3d) @@ -10720,19 +10754,18 @@ static void library_link_end(Main *mainl, /* Give a base to loose objects and collections. * Only directly linked objects & collections are instantiated by - * #BLO_library_link_named_part_ex & co, + * #BLO_library_link_named_part & co, * here we handle indirect ones and other possible edge-cases. */ - if (scene) { - add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); - add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); - } - else { - /* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */ - } + if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) { + /* Should always be true. */ + if (scene != NULL) { + add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); + add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag); + } - /* Clear objects and collections instantiating tag. */ - BKE_main_id_tag_listbase(&(mainvar->objects), LIB_TAG_DOIT, false); - BKE_main_id_tag_listbase(&(mainvar->collections), LIB_TAG_DOIT, false); + /* Clear objects and collections instantiating tag. */ + library_link_clear_tag(mainvar, flag); + } /* patch to prevent switch_endian happens twice */ if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) { @@ -10748,25 +10781,18 @@ static void library_link_end(Main *mainl, * * \param mainl: The main database to link from (not the active one). * \param bh: The blender file handle (WARNING! may be freed by this function!). - * \param flag: Options for linking, used for instantiating. - * \param bmain: The main database in which to instantiate objects/collections - * \param scene: The scene in which to instantiate objects/collections - * (if NULL, no instantiation is done). - * \param view_layer: The scene layer in which to instantiate objects/collections - * (if NULL, no instantiation is done). - * \param v3d: The active 3D viewport - * (only to define local-view for instantiated objects & groups, can be NULL). + * \param params: Settings for linking that don't change from beginning to end of linking. */ -void BLO_library_link_end(Main *mainl, - BlendHandle **bh, - int flag, - Main *bmain, - Scene *scene, - ViewLayer *view_layer, - const View3D *v3d) +void BLO_library_link_end(Main *mainl, BlendHandle **bh, const struct LibraryLink_Params *params) { FileData *fd = (FileData *)(*bh); - library_link_end(mainl, &fd, flag, bmain, scene, view_layer, v3d); + library_link_end(mainl, + &fd, + params->bmain, + params->flag, + params->context.scene, + params->context.view_layer, + params->context.v3d); *bh = (BlendHandle *)fd; } diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index bdad4d03ae7..a3750d348f5 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -327,7 +327,10 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &(self->blo_handle), self->relpath); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init(&liblink_params, bmain, self->flag); + + mainl = BLO_library_link_begin(&(self->blo_handle), self->relpath, &liblink_params); { int idcode_step = 0, idcode; @@ -350,7 +353,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) if (item_idname) { ID *id = BLO_library_link_named_part( - mainl, &(self->blo_handle), idcode, item_idname); + mainl, &(self->blo_handle), idcode, item_idname, &liblink_params); if (id) { #ifdef USE_RNA_DATABLOCKS /* swap name for pointer to the id */ @@ -394,7 +397,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args)) } Library *lib = mainl->curlib; /* newly added lib, assign before append end */ - BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL); + BLO_library_link_end(mainl, &(self->blo_handle), &liblink_params); BLO_blendhandle_close(self->blo_handle); self->blo_handle = NULL; diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 6ccc5d79962..8c14055696c 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -250,7 +250,11 @@ static void wm_link_do(WMLinkAppendData *lapp_data, } /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &bh, libname); + struct LibraryLink_Params liblink_params; + BLO_library_link_params_init_with_context( + &liblink_params, bmain, flag, scene, view_layer, v3d); + + mainl = BLO_library_link_begin(&bh, libname, &liblink_params); lib = mainl->curlib; BLI_assert(lib); UNUSED_VARS_NDEBUG(lib); @@ -276,7 +280,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data, continue; } - new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag); + new_id = BLO_library_link_named_part(mainl, &bh, item->idcode, item->name, &liblink_params); if (new_id) { /* If the link is successful, clear item's libs 'todo' flags. @@ -286,7 +290,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data, } } - BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d); + BLO_library_link_end(mainl, &bh, &liblink_params); BLO_blendhandle_close(bh); } } |