[Bf-blender-cvs] [e451d9b] asset-experiments: WIP (mostly empty for now) code to actually reload assets reported as needing it by update_check.

Bastien Montagne noreply at git.blender.org
Thu Apr 28 23:16:50 CEST 2016


Commit: e451d9b56ad53ba587d1b4530ce7c7731dd7409b
Author: Bastien Montagne
Date:   Thu Apr 28 21:44:59 2016 +0200
Branches: asset-experiments
https://developer.blender.org/rBe451d9b56ad53ba587d1b4530ce7c7731dd7409b

WIP (mostly empty for now) code to actually reload assets reported as needing it by update_check.

===================================================================

M	release/scripts/startup/bl_ui/space_info.py
M	source/blender/windowmanager/intern/wm_files_link.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/wm_files.h

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index ae68281..5374919 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -72,8 +72,8 @@ class INFO_HT_header(Header):
             row.operator("script.assets_warn_clear", text="Ignore")
             if bpy.app.assets_need_reload is True and bpy.app.assets_quiet is False:
                 row.label("Some assets have to be reloaded", icon='INFO')
-                row.label(icon='SCREEN_BACK', text="Reload Assets")
-                #~ row.operator("wm.reload_assets", icon='SCREEN_BACK', text="Reload Assets")
+                #~ row.label(icon='SCREEN_BACK', text="Reload Assets")
+                row.operator("wm.assets_reload", icon='SCREEN_BACK', text="Reload Assets")
             if bpy.app.assets_fail is True and bpy.app.assets_quiet is False:
                 row.label("Some asset engine(s) failed to retrieve updated data about their assets...", icon='ERROR')
             return
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 54ebcab..25991ad 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -1244,4 +1244,362 @@ void WM_OT_assets_update_check(wmOperatorType *ot)
 	ot->exec = wm_assets_update_check_exec;
 }
 
+static int wm_assets_reload_exec(bContext *C, wmOperator *op)
+{
+	/* We need to:
+	 *   - get list of all asset IDs to reload (either via given uuids, or their tag), and regroup them by asset engine.
+	 *   - tag somehow all their indirect 'dependencies' IDs.
+	 *   - call load_pre to get actual filepaths.
+	 *   - do reload/relocate and remap as in lib_reload.
+	 *   - cleanup indirect dependencies IDs with zero users.
+	 */
+	Main *bmain = CTX_data_main(C);
+
+	ListBase engines = {NULL};
+
+	/* For now, ignore the uuids list of op. */
+	asset_update_engines_uuids_fetch(&engines, bmain, NULL, UUID_TAG_ASSET_RELOAD, false);
+
+	for (AssetUpdateCheckEngine *auce = engines.first; auce; auce = auce->next) {
+		BKE_asset_engine_free(auce->ae);
+		MEM_freeN(auce->uuids.uuids);
+	}
+	BLI_freelistN(&engines);
+
+	G.f &= ~G_ASSETS_NEED_RELOAD;
+	return OPERATOR_CANCELLED;
+
+#if 0
+	Library *lib;
+	char lib_name[MAX_NAME];
+
+	RNA_string_get(op->ptr, "library", lib_name);
+	lib = (Library *)BKE_libblock_find_name_ex(CTX_data_main(C), ID_LI, lib_name);
+
+	if (lib) {
+		Main *bmain = CTX_data_main(C);
+		Scene *scene = CTX_data_scene(C);
+		PropertyRNA *prop;
+		WMLinkAppendData *lapp_data;
+
+		ListBase *lbarray[MAX_LIBARRAY];
+		int lba_idx;
+
+		LinkNode *itemlink;
+		int item_idx;
+
+		int num_ids;
+		char path[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
+		short flag = 0;
+
+		if (RNA_boolean_get(op->ptr, "relative_path")) {
+			flag |= FILE_RELPATH;
+		}
+
+		if (lib->parent && !reload) {
+			BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT,
+			            "Cannot relocate indirectly linked library '%s'", lib->filepath);
+			return OPERATOR_CANCELLED;
+		}
+
+		RNA_string_get(op->ptr, "directory", root);
+		RNA_string_get(op->ptr, "filename", libname);
+
+		if (!BLO_has_bfile_extension(libname)) {
+			BKE_report(op->reports, RPT_ERROR, "Not a library");
+			return OPERATOR_CANCELLED;
+		}
+
+		BLI_join_dirfile(path, sizeof(path), root, libname);
+
+		if (BLI_path_cmp(lib->filepath, path) == 0) {
+			printf("We are supposed to reload '%s' lib (%d)...\n", lib->filepath, lib->id.us);
+
+			lapp_data = wm_link_append_data_new(flag);
+			wm_link_append_data_library_add(lapp_data, path);
+
+			BKE_main_lock(bmain);
+
+			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);
+
+						printf("\tdatablock to seek for: %s\n", id->name);
+					}
+				}
+			}
+
+			BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
+
+			/* XXX For now, locking is not reentrant so it's not safe to call core linking code with locked Main. */
+			BKE_main_unlock(bmain);
+
+			/* We do not want any instanciation here! */
+			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL, NULL, true, true);
+
+			BKE_main_lock(bmain);
+
+			/* We add back old id to bmain.
+			 * We need to do this in a first, separated loop, otherwise some of those may not be handled by
+			 * ID remapping, which means they would still reference old data to be deleted... */
+			for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
+				WMLinkAppendDataItem *item = itemlink->link;
+				ID *old_id = item->customdata;
+
+				BLI_assert(old_id);
+				BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
+			}
+
+			for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
+				WMLinkAppendDataItem *item = itemlink->link;
+				ID *old_id = item->customdata;
+				ID *new_id = item->new_id;
+
+				/* Since we asked for placeholders in case of missing IDs, we expect to always get a valid one. */
+				BLI_assert(new_id);
+				if (new_id) {
+//					printf("before remap, old_id users: %d (%p), new_id users: %d (%p)\n", old_id->us, old_id, new_id->us, new_id);
+					/* Note that here, we also want to replace indirect usages. */
+					BKE_libblock_remap_locked(bmain, old_id, new_id, ID_REMAP_SKIP_NEVER_NULL_USAGE);
+
+//					printf("after remap, old_id users: %d, new_id users: %d\n", old_id->us, new_id->us);
+
+					/* In some cases, new_id might become direct link, remove parent of library in this case. */
+					if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) {
+						BLI_assert(0);  /* Should not happen in reload case... */
+						new_id->lib->parent = NULL;
+					}
+				}
+
+				if (old_id->us > 0 && new_id) {
+					size_t len = strlen(old_id->name);
+
+					/* XXX TODO This is utterly weak!!! */
+					if (len > MAX_ID_NAME - 3 && old_id->name[len - 4] == '.') {
+						old_id->name[len - 6] = '.';
+						old_id->name[len - 5] = 'P';
+					}
+					else {
+						len = MIN2(len, MAX_ID_NAME - 3);
+						old_id->name[len] = '.';
+						old_id->name[len + 1] = 'P';
+						old_id->name[len + 2] = '\0';
+					}
+
+					id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id);
+
+					BKE_reportf(op->reports, RPT_WARNING,
+					            "Lib Reload: Replacing all references to old datablock '%s' by reloaded one failed, "
+					            "old one (%d remaining users) had to be kept and was renamed to '%s'",
+					            new_id->name, old_id->us, old_id->name);
+				}
+			}
+
+			BKE_main_unlock(bmain);
+
+			for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
+				WMLinkAppendDataItem *item = itemlink->link;
+				ID *old_id = item->customdata;
+
+//				printf("%p\n", old_id);
+
+				if (old_id->us == 0) {
+					BKE_libblock_free(bmain, old_id);
+					num_ids--;
+				}
+			}
+
+			wm_link_append_data_free(lapp_data);
+		}
+		else {
+			int totfiles = 0;
+
+			printf("We are supposed to relocate '%s' lib to new '%s' one...\n", lib->filepath, libname);
+
+			/* Check if something is indicated for relocate. */
+			prop = RNA_struct_find_property(op->ptr, "files");
+			if (prop) {
+				totfiles = RNA_property_collection_length(op->ptr, prop);
+				if (totfiles == 0) {
+					if (!libname[0]) {
+						BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+						return OPERATOR_CANCELLED;
+					}
+				}
+			}
+
+			lapp_data = wm_link_append_data_new(flag);
+
+			if (totfiles) {
+				RNA_BEGIN (op->ptr, itemptr, "files")
+				{
+					RNA_string_get(&itemptr, "name", relname);
+
+					BLI_join_dirfile(path, sizeof(path), root, relname);
+
+					if (BLI_path_cmp(path, lib->filepath) == 0 || !BLO_has_bfile_extension(relname)) {
+						continue;
+					}
+
+					printf("\t candidate new lib to reload datablocks from: %s\n", path);
+					wm_link_append_data_library_add(lapp_data, path);
+				}
+				RNA_END;
+			}
+			else {
+				printf("\t candidate new lib to reload datablocks from: %s\n", path);
+				wm_link_append_data_library_add(lapp_data, path);
+			}
+
+			BKE_main_lock(bmain);
+
+			lba_idx = set_listbasepointers(bmain, lbarray);
+			while (lba_idx--) {
+				ID *id = lbarray[lba_idx]->first;
+				const int idcode = id ? GS(id->name) : 0;
+
+				if (!id || !BKE_idcode_is_linkable(idcode)) {
+					continue;
+				}
+				for (; id; id = id->next) {
+					if (id->lib == lib) {
+						WMLinkAppendDataItem *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);
+
+						printf("\tdatablock to seek for: %s\n", id->name);
+					}
+				}
+			}
+
+			BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
+
+			/* XXX For now, locking is not reentrant so it's not safe to call core linking code with locked Main. */
+			BKE_main_unlock(bmain);
+
+			/* We do not want any instanciation here! */
+			wm_link_do(lapp_data, op->reports, bmain, NULL, NULL, NULL, false, false);
+
+			BKE_main_lock(bmain);
+
+			for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
+				WMLinkAppendDataItem *item = itemlink->link;
+				ID *old_id = item->customdata;
+				ID *new_id = item->new_id;
+
+				BLI_assert(old_id);
+				if (new_id) {
+//					printf("before remap, old_id users: %d, new_id

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list