[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