[Bf-blender-cvs] [aec90073ee0] uuid-undo-experiments: Merge branch 'uuid-id' into uuid-undo-experiments
Bastien Montagne
noreply at git.blender.org
Mon Mar 2 16:25:25 CET 2020
Commit: aec90073ee00c8893fa41475c14c48311efd06c4
Author: Bastien Montagne
Date: Mon Mar 2 16:14:53 2020 +0100
Branches: uuid-undo-experiments
https://developer.blender.org/rBaec90073ee00c8893fa41475c14c48311efd06c4
Merge branch 'uuid-id' into uuid-undo-experiments
===================================================================
===================================================================
diff --cc source/blender/blenloader/intern/readfile.c
index 5b83bc0cd03,7a1c9623b19..b9a305bbf1f
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@@ -2217,23 -2179,6 +2217,23 @@@ void blo_add_library_pointer_map(ListBa
fd->old_mainlist = old_mainlist;
}
+/* Build idmap of old main (we only care about local data here, so we can do that after
+ * split_main() call. */
+void blo_make_idmap_from_main(FileData *fd, Main *bmain)
+{
+ if (fd->old_idmap != NULL) {
+ BKE_main_idmap_destroy(fd->old_idmap);
+ }
- fd->old_idmap = BKE_main_idmap_create(bmain, false, NULL);
++ fd->old_idmap = BKE_main_idmap_create(bmain, false, NULL, MAIN_IDMAP_TYPE_UUID);
+}
+
+/* Create sibling mapping of libmap (i.e. old ID pointer values to new valid IDs), but for the
+ * addresses from old main. */
+void blo_make_undo_reused_libmap(FileData *fd)
+{
+ fd->libmap_undo_reused = oldnewmap_new();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@@ -9063,102 -9005,15 +9064,102 @@@ static BHead *read_libblock(FileData *f
}
/* read libblock */
+ fd->are_memchunks_identical = true;
id = read_struct(fd, bhead, "lib block");
- if (id) {
+ BHead *id_bhead = bhead;
+
+ if (id != NULL) {
const short idcode = GS(id->name);
+ const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
+
+ if (id_bhead->code != ID_LINK_PLACEHOLDER) {
+ /* need a name for the mallocN, just for debugging and sane prints on leaks */
+ allocname = dataname(idcode);
+
+ /* read all data into fd->datamap */
+ /* TODO: instead of building oldnewmap here we could just quickly check the bheads... could
+ * save some more ticks. Probably not worth it though, bottleneck is full depsgraph rebuild
+ * and eval, not actual file reading. */
+ bhead = read_data_into_oldnewmap(fd, id_bhead, allocname);
+
+ DEBUG_PRINTF(
+ "%s: ID %s is unchanged: %d\n", __func__, id->name, fd->are_memchunks_identical);
+
+ if (fd->memfile != NULL) {
+ BLI_assert(fd->old_idmap != NULL || !do_partial_undo);
+ /* This code should only ever be reached for local data-blocks. */
+ BLI_assert(main->curlib == NULL);
+
+ /* Find the 'current' existing ID we want to reuse instead of the one we would read from
+ * the undo memfile. */
+ ID *id_old = do_partial_undo ?
- BKE_main_idmap_lookup(fd->old_idmap, idcode, id->name + 2, NULL) :
++ BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid) :
+ NULL;
+ bool can_finalize_and_return = false;
+
+ if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
+ /* Read WindowManager, Screen and WorkSpace IDs are never actually used during undo (see
+ * `setup_app_data()` in `blendfile.c`).
+ * So we can just abort here, just ensuring libmapping is set accordingly. */
+ can_finalize_and_return = true;
+ }
+ else if (id_old != NULL && fd->are_memchunks_identical) {
+ /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as
+ * this is only for do_version-like code), but for sake of consistency, and also because
+ * it will tell us which ID is re-used from old Main, and which one is actually new. */
+ id_old->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_UNDO_OLD_ID_REUSED;
+ id_old->lib = main->curlib;
+ id_old->us = ID_FAKE_USERS(id_old);
+ /* Do not reset id->icon_id here, memory allocated for it remains valid. */
+ /* Needed because .blend may have been saved with crap value here... */
+ id_old->newid = NULL;
+ id_old->orig_id = NULL;
+
+ Main *old_bmain = fd->old_mainlist->first;
+ BLI_assert(old_bmain == BKE_main_idmap_main_get(fd->old_idmap));
+ ListBase *old_lb = which_libbase(old_bmain, idcode);
+ ListBase *new_lb = which_libbase(main, idcode);
+ BLI_remlink(old_lb, id_old);
+ BLI_addtail(new_lb, id_old);
+
+ can_finalize_and_return = true;
+ }
+
+ if (can_finalize_and_return) {
+ oldnewmap_insert(fd->libmap, id_bhead->old, id_old, id_bhead->code);
+ if (id_old != NULL) {
+ oldnewmap_insert(fd->libmap_undo_reused, id_old, id_old, id_bhead->code);
+ }
+
+ if (r_id) {
+ *r_id = id_old;
+ }
+
+ MEM_freeN(id);
+ oldnewmap_free_unused(fd->datamap);
+ oldnewmap_clear(fd->datamap);
+
+ return bhead;
+ }
+ }
+ }
+
/* do after read_struct, for dna reconstruct */
lb = which_libbase(main, idcode);
if (lb) {
/* for ID_LINK_PLACEHOLDER check */
- oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
+ oldnewmap_insert(fd->libmap, id_bhead->old, id, id_bhead->code);
+
+ /* Some re-used old IDs might also use newly read ones, so we have to check for old memory
+ * addresses for those as well. */
+ if (fd->memfile != NULL && do_partial_undo && id->lib == NULL) {
+ BLI_assert(fd->old_idmap != NULL);
- ID *id_old = BKE_main_idmap_lookup(fd->old_idmap, idcode, id->name + 2, NULL);
++ ID *id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid);
+ if (id_old != NULL) {
+ oldnewmap_insert(fd->libmap_undo_reused, id_old, id, id_bhead->code);
+ }
+ }
BLI_addtail(lb, id);
More information about the Bf-blender-cvs
mailing list