diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_files_link.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_files_link.c | 156 |
1 files changed, 88 insertions, 68 deletions
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index f3792e0bac6..8195212f3c3 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -62,7 +62,7 @@ #include "BLO_readfile.h" -#include "BKE_asset.h" +#include "BKE_asset_engine.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_library.h" @@ -691,9 +691,13 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN return OPERATOR_CANCELLED; } -/* Note that IDs listed in lapp_data items *must* have been removed from bmain by caller. */ +/** + * \param library if given, all IDs from that library will be removed and reloaded. Otherwise, IDs must have already + * been removed from \a bmain, and added to \a lapp_data. + */ static void lib_relocate_do( - Main *bmain, WMLinkAppendData *lapp_data, ReportList *reports, AssetEngineType *aet, const bool do_reload) + Main *bmain, Scene *scene, + Library *library, WMLinkAppendData *lapp_data, ReportList *reports, AssetEngineType *aet, const bool do_reload) { ListBase *lbarray[MAX_LIBARRAY]; int lba_idx; @@ -701,6 +705,36 @@ static void lib_relocate_do( LinkNode *itemlink; int item_idx; + /* Remove all IDs to be reloaded from Main. */ + if (library) { + lba_idx = set_listbasepointers(bmain, lbarray); + while (lba_idx--) { + ID *id = lbarray[lba_idx]->first; + const short idcode = id ? GS(id->name) : 0; + + if (!id || !BKE_idcode_is_linkable(idcode)) { + /* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */ + continue; + } + + for (; id; id = id->next) { + if (id->lib == library) { + WMLinkAppendDataItem *item; + + /* We remove it from current Main, and add it to items to link... */ + /* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */ + BLI_remlink(lbarray[lba_idx], id); + item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, NULL, id); + BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); + +#ifdef PRINT_DEBUG + printf("\tdatablock to seek for: %s\n", id->name); +#endif + } + } + } + } + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* We do not want any instanciation here! */ @@ -839,6 +873,43 @@ static void lib_relocate_do( } } } + + BKE_main_lib_objects_recalc_all(bmain); + IMB_colormanagement_check_file_config(bmain); + + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); + + /* recreate dependency graph to include new objects */ + DAG_scene_relations_rebuild(bmain, scene); + + /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ + GPU_materials_free(); +} + +void WM_lib_reload(Library *lib, bContext *C, ReportList *reports) +{ + if (!BLO_has_bfile_extension(lib->filepath)) { + BKE_reportf(reports, RPT_ERROR, "'%s' is not a valid library filepath", lib->filepath); + return; + } + + if (!BLI_exists(lib->filepath)) { + BKE_reportf(reports, RPT_ERROR, + "Trying to reload library '%s' from invalid path '%s'", lib->id.name, lib->filepath); + return; + } + + WMLinkAppendData *lapp_data = wm_link_append_data_new(0); + + wm_link_append_data_library_add(lapp_data, lib->filepath); + + lib_relocate_do(CTX_data_main(C), CTX_data_scene(C), lib, lapp_data, reports, NULL, true); + + wm_link_append_data_free(lapp_data); + + WM_event_add_notifier(C, NC_WINDOW, NULL); } static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) @@ -855,9 +926,6 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) PropertyRNA *prop; WMLinkAppendData *lapp_data; - ListBase *lbarray[MAX_LIBARRAY]; - int lba_idx; - char path[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; short flag = 0; @@ -949,50 +1017,10 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) } } - lba_idx = set_listbasepointers(bmain, lbarray); - while (lba_idx--) { - ID *id = lbarray[lba_idx]->first; - const short idcode = id ? GS(id->name) : 0; - - if (!id || !BKE_idcode_is_linkable(idcode)) { - /* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */ - continue; - } - - for (; id; id = id->next) { - if (id->lib == lib) { - WMLinkAppendDataItem *item; - - /* We remove it from current Main, and add it to items to link... */ - /* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */ - BLI_remlink(lbarray[lba_idx], id); - item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, NULL, id); - BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); - -#ifdef PRINT_DEBUG - printf("\tdatablock to seek for: %s\n", id->name); -#endif - } - } - } - - lib_relocate_do(bmain, lapp_data, op->reports, NULL, do_reload); + lib_relocate_do(bmain, scene, lib, lapp_data, op->reports, NULL, do_reload); wm_link_append_data_free(lapp_data); - BKE_main_lib_objects_recalc_all(bmain); - IMB_colormanagement_check_file_config(bmain); - - /* important we unset, otherwise these object wont - * link into other scenes from this blend file */ - BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); - - /* recreate dependency graph to include new objects */ - DAG_scene_relations_rebuild(bmain, scene); - - /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ - GPU_materials_free(); - /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */ BLI_strncpy(G.lib, root, FILE_MAX); @@ -1066,9 +1094,10 @@ typedef struct AssetUpdateCheckEngine { AssetEngine *ae; /* Note: We cannot store IDs themselves in non-locking async task... so we'll have to check again for - * UUID/IDs mapping on each update call... Not ideal, but don't think it will be that big of an override + * UUID/IDs mapping on each update call... Not ideal, but don't think it will be that big of a bottleneck * in practice. */ AssetUUIDList uuids; + int allocated_uuids; int ae_job_id; short status; } AssetUpdateCheckEngine; @@ -1170,13 +1199,16 @@ static void asset_update_engines_uuids_fetch( id->uuid->tag = (id->tag & LIB_TAG_MISSING) ? UUID_TAG_ASSET_MISSING : 0; } - /* XXX horrible, need to use some mempool, stack or something :) */ auce->uuids.nbr_uuids++; - if (auce->uuids.uuids) { - auce->uuids.uuids = MEM_reallocN_id(auce->uuids.uuids, sizeof(*auce->uuids.uuids) * (size_t)auce->uuids.nbr_uuids, __func__); - } - else { - auce->uuids.uuids = MEM_mallocN(sizeof(*auce->uuids.uuids) * (size_t)auce->uuids.nbr_uuids, __func__); + BKE_asset_uuid_print(id->uuid); + if (auce->uuids.nbr_uuids > auce->allocated_uuids) { + auce->allocated_uuids += 16; + BLI_assert(auce->uuids.nbr_uuids < auce->allocated_uuids); + + const size_t allocsize = sizeof(*auce->uuids.uuids) * (size_t)auce->allocated_uuids; + auce->uuids.uuids = auce->uuids.uuids ? + MEM_reallocN_id(auce->uuids.uuids, allocsize, __func__) : + MEM_mallocN(allocsize, __func__); } auce->uuids.uuids[auce->uuids.nbr_uuids - 1] = *id->uuid; } @@ -1381,6 +1413,7 @@ static int wm_assets_reload_exec(bContext *C, wmOperator *op) * - cleanup indirect dependencies IDs with zero users. */ Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); ListBase engines = {NULL}; @@ -1461,7 +1494,7 @@ static int wm_assets_reload_exec(bContext *C, wmOperator *op) } } - lib_relocate_do(bmain, lapp_data, op->reports, auce->ae->type, do_reload); + lib_relocate_do(bmain, scene, NULL, lapp_data, op->reports, auce->ae->type, do_reload); wm_link_append_data_free(lapp_data); BLI_ghash_free(libraries, MEM_freeN, NULL); @@ -1476,19 +1509,6 @@ static int wm_assets_reload_exec(bContext *C, wmOperator *op) } BLI_freelistN(&engines); - BKE_main_lib_objects_recalc_all(bmain); - IMB_colormanagement_check_file_config(bmain); - - /* important we unset, otherwise these object wont - * link into other scenes from this blend file */ - BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); - - /* recreate dependency graph to include new objects */ - DAG_scene_relations_rebuild(bmain, CTX_data_scene(C)); - - /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ - GPU_materials_free(); - WM_event_add_notifier(C, NC_WINDOW, NULL); G.f &= ~G_ASSETS_NEED_RELOAD; |