[Bf-blender-cvs] [bde25459d61] uuid-undo-experiments-swap-reread-datablocks: Merge branch 'uuid-undo-experiments' into uuid-undo-experiments-swap-reread-datablocks
Bastien Montagne
noreply at git.blender.org
Mon Mar 2 17:52:43 CET 2020
Commit: bde25459d612da77588e95fa279067933bf1b30d
Author: Bastien Montagne
Date: Mon Mar 2 17:23:51 2020 +0100
Branches: uuid-undo-experiments-swap-reread-datablocks
https://developer.blender.org/rBbde25459d612da77588e95fa279067933bf1b30d
Merge branch 'uuid-undo-experiments' into uuid-undo-experiments-swap-reread-datablocks
Conflicts:
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_ID.h
===================================================================
===================================================================
diff --cc source/blender/blenloader/intern/readblenentry.c
index c37770277e7,dbcfee0b690..085e500f7e5
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@@ -387,7 -387,11 +387,7 @@@ BlendFileData *BLO_read_from_memfile(Ma
if ((params->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) {
/* Build idmap of old main (we only care about local data here, so we can do that after
* split_main() call. */
- blo_make_old_valid_ids_from_main(fd, old_mainlist.first);
- blo_make_idmap_from_main(fd, old_mainlist.first);
-
- /* Create sibling mapping of libmap (i.e. old ID pointer values to new valid IDs), but for
- * the addresses from old main. */
- blo_make_undo_reused_libmap(fd);
++ blo_make_old_idmap_from_main(fd, old_mainlist.first);
}
/* makes lookup of existing images in old main */
diff --cc source/blender/blenloader/intern/readfile.c
index 85bb5850105,b9a305bbf1f..0decf6f8411
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@@ -1599,8 -1598,11 +1599,8 @@@ void blo_filedata_free(FileData *fd
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) {
oldnewmap_free(fd->libmap);
}
- if (fd->old_valid_ids != NULL) {
- BLI_gset_free(fd->old_valid_ids, NULL);
- if (fd->libmap_undo_reused != NULL) {
- oldnewmap_free(fd->libmap_undo_reused);
- }
+ if (fd->old_idmap != NULL) {
+ BKE_main_idmap_destroy(fd->old_idmap);
}
if (fd->bheadmap) {
MEM_freeN(fd->bheadmap);
@@@ -2215,24 -2217,23 +2215,16 @@@ 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
+/* Build a GSet of old main (we only care about local data here, so we can do that after
* split_main() call. */
- void blo_make_old_valid_ids_from_main(FileData *fd, Main *bmain)
-void blo_make_idmap_from_main(FileData *fd, Main *bmain)
++void blo_make_old_idmap_from_main(FileData *fd, Main *bmain)
{
- if (fd->old_valid_ids != NULL) {
- BLI_gset_clear(fd->old_valid_ids, NULL);
+ if (fd->old_idmap != NULL) {
+ BKE_main_idmap_destroy(fd->old_idmap);
}
- else {
- fd->old_valid_ids = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
- }
-
- ID *id;
- FOREACH_MAIN_ID_BEGIN (bmain, id) {
- BLI_gset_add(fd->old_valid_ids, id);
- }
- FOREACH_MAIN_ID_END;
+ 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();
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@@ -9080,17 -9066,12 +9075,15 @@@ static BHead *read_libblock(FileData *f
/* read libblock */
fd->are_memchunks_identical = true;
id = read_struct(fd, bhead, "lib block");
+ const short idcode = id != NULL ? GS(id->name) : 0;
BHead *id_bhead = bhead;
+ /* Used when undoing from memfile, we swap changed IDs into their old addresses when found. */
+ ID *id_old = NULL;
- void *id_old_memh = NULL;
+ bool do_id_swap = false;
if (id != NULL) {
- const short idcode = GS(id->name);
const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
- LinkNode *used_id_chain = NULL;
if (id_bhead->code != ID_LINK_PLACEHOLDER) {
/* need a name for the mallocN, just for debugging and sane prints on leaks */
@@@ -9112,14 -9093,9 +9105,8 @@@
/* Find the 'current' existing ID we want to reuse instead of the one we would read from
* the undo memfile. */
- if (do_partial_undo) {
- id_old_memh = id_old = id_bhead->old;
- if (!BLI_gset_haskey(fd->old_valid_ids, id_old)) {
- DEBUG_PRINTF("Found an old, invalid id_old pointer for new %s\n", id->name);
- id_old = NULL;
- used_id_chain = NULL;
- }
- }
- ID *id_old = do_partial_undo ?
- BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid) :
- NULL;
++ id_old = do_partial_undo ? 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)) {
@@@ -9154,11 -9127,10 +9141,9 @@@
}
if (can_finalize_and_return) {
+ DEBUG_PRINTF("Re-using existing ID %s instead of newly read one\n", id_old->name);
oldnewmap_insert(fd->libmap, id_bhead->old, id_old, id_bhead->code);
- for (; used_id_chain; used_id_chain = used_id_chain->next) {
- oldnewmap_insert(fd->libmap, used_id_chain->link, id_old, id_bhead->code);
- if (id_old != NULL) {
- oldnewmap_insert(fd->libmap_undo_reused, id_old, id_old, id_bhead->code);
-- }
++ oldnewmap_insert(fd->libmap, id_old, id_old, id_bhead->code);
if (r_id) {
*r_id = id_old;
@@@ -9179,43 -9151,19 +9164,36 @@@
/* 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_valid_ids != NULL);
- if (id_old == NULL) {
- id_old_memh = id_old = id_bhead->old;
- if (!BLI_gset_haskey(fd->old_valid_ids, id_old)) {
- DEBUG_PRINTF("Found an old, invalid id_old pointer for new %s\n", id->name);
- id_old = NULL;
- used_id_chain = NULL;
- }
- }
+ BLI_assert(fd->old_idmap != NULL);
- ID *id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid);
++ 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_assert(MEM_allocN_len(id) == MEM_allocN_len(id_old));
+ /* UI IDs are always re-used from old bmain at higher-level calling code, so never swap
+ * those. Besides maybe custom properties, no other ID should have pointers to those
+ * anyway...
+ * And linked IDs are handled separately as well. */
+ do_id_swap = !ELEM(idcode, ID_WM, ID_SCR, ID_WS) &&
+ !(id_bhead->code == ID_LINK_PLACEHOLDER);
}
}
+ /* At this point, we know we are going to keep that newly read & allocated ID, so we need to
+ * reallocate it to ensure we actually get a unique memory address for it. */
+ if (!do_id_swap) {
+ DEBUG_PRINTF("using newly-read ID %s to a new mem address\n", id->name);
+ }
+ else {
+ DEBUG_PRINTF("using newly-read ID %s to its old, already existing address\n", id->name);
+ }
+
+ /* for ID_LINK_PLACEHOLDER check */
+ ID *id_target = do_id_swap ? id_old : id;
+ oldnewmap_insert(fd->libmap, id_bhead->old, id_target, id_bhead->code);
- for (; used_id_chain; used_id_chain = used_id_chain->next) {
- oldnewmap_insert(fd->libmap, used_id_chain->link, id_target, id_bhead->code);
- }
++ oldnewmap_insert(fd->libmap, id_old, id_target, id_bhead->code);
+
BLI_addtail(lb, id);
+
+ BKE_lib_libblock_uuid_generate(id);
}
else {
/* unknown ID type */
diff --cc source/blender/blenloader/intern/readfile.h
index 7739beaf78d,c6cd123f99e..4965845d167
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@@ -135,7 -135,7 +135,7 @@@ typedef struct FileData
ListBase *mainlist;
/** Used for undo. */
ListBase *old_mainlist;
- struct GSet *old_valid_ids;
- IDNameLib_Map *old_idmap;
++ struct IDNameLib_Map *old_idmap;
struct ReportList *reports;
} FileData;
@@@ -167,7 -167,8 +167,7 @@@ void blo_end_sound_pointer_map(FileDat
void blo_make_packed_pointer_map(FileData *fd, struct Main *oldmain);
void blo_end_packed_pointer_map(FileData *fd, struct Main *oldmain);
void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd);
- void blo_make_old_valid_ids_from_main(FileData *fd, struct Main *bmain);
-void blo_make_idmap_from_main(FileData *fd, struct Main *bmain);
-void blo_make_undo_reused_libmap(FileData *fd);
++void blo_make_old_idmap_from_main(FileData *fd, struct Main *bmain);
void blo_filedata_free(FileData *fd);
diff --cc source/blender/makesdna/DNA_ID.h
index 3bc79044e61,4dc177a137a..28c21468249
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@@ -243,10 -245,13 +245,21 @@@ typedef struct ID
int us;
int icon_id;
int recalc;
- /* Used by undo code. Value of recalc is stored there when reading an ID from memfile, and not
++ /**
++ * Used by undo code. Value of recalc is stored there when reading an ID from memfile, and not
+ * touched by anything, which means it can be used as 'reference' recalc value for the next undo
- * step, when going backward (i.e. actual undo, redo can just use recalc value directly). */
++ * step, when going backward (i.e. actual undo, redo can just use recalc value directly).
++ */
+ int recalc_undo_accumulated;
+
+ /**
+ * A session-wide unique identifier for a given ID, that remain the same across potential
+ * re-allocations (e.g. due to undo/redo steps).
+ */
+ unsigned int session_uuid;
+
++ char _pad[4];
++
IDProperty *properties;
/** Reference linked ID which this one overrides. */
More information about the Bf-blender-cvs
mailing list