[Bf-blender-cvs] [176a3adcfdc] undo-experiments-idnames: undoexp: Initial, *VERY* basic code using ID names.

Bastien Montagne noreply at git.blender.org
Fri Jan 3 11:34:37 CET 2020


Commit: 176a3adcfdca7d33400e0117deaa723f8bcab368
Author: Bastien Montagne
Date:   Thu Jan 2 20:50:09 2020 +0100
Branches: undo-experiments-idnames
https://developer.blender.org/rB176a3adcfdca7d33400e0117deaa723f8bcab368

undoexp: Initial, *VERY* basic code using ID names.

This comes from the fact that we are now handling IDs from potentially
many different 'memory realms' (at the very least, two of them, those
read from memfile [new IDs], and those from previous Main [old IDs]).

The main consequence is that using pointers (aka memory addresses) as
'uids' is not working anymore: we'd need to keep some sort of 'history'
of all pointers a given data-block has had to get it working, and that
would likely lead to 'pointer collisions' [1] at some point or another.

So instead we need to use the only kind of uid we have for datablocks:
their names.

That patch is very basic, but it is enough to check undo/redo on basic
object and pose-bone-of-rigged-mesh dummies, not get it crashing, and
demonstrate huges speed-up in some artificial 'worst test case' scenario.

There are still several things to do from there:
* IDname handling:
  * Obviously, use a ghash instead of dummy linear list search! Most
    likely use BKE_library_idmap code to generate it.
  * Check and handle pointers collisions. [1]
* Testing, testing and moar testing! These changes are highly dangerous
  and can destroy a blend file completely, so we'll need to be 100% sure
  they are working perfectly before puting them in master!

[1] Pointer collision: the issue here is with 'old' memory addresses
stored/used as uid in .blend file. When one read a .blend file as a
whole this is not an issue, since all old data-blocks where in a single
'memory realm' (the old Main valid at time of file writing), and all new
data-blocks are also in a single realm (the newly read file). Since we
only remap each pointer once, this is fine.

But when we start mixing those 'memory realms' by re-using IDs from old
Main in this undo project, we can end up with the same 'uuid' old
pointer value having to be remapped to two different new addresses.

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

M	source/blender/blenloader/intern/readfile.c

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5444c4ed04e..f5a72f0924b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9454,9 +9454,10 @@ static BHead *read_libblock(FileData *fd,
         Main *old_bmain = fd->old_mainlist->first;
         ListBase *old_lb = which_libbase(old_bmain, idcode);
         BLI_assert(old_lb != NULL);
-        if (BLI_findindex(old_lb, id_bhead->old) != -1) {
+        ID *id_old = NULL;
+        if ((id_old = BLI_findstring(old_lb, id->name, offsetof(ID, name))) != NULL) {
           MEM_freeN(id);
-          id = (ID *)id_bhead->old;
+          id = id_old;
 
           /* 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
@@ -9469,6 +9470,7 @@ static BHead *read_libblock(FileData *fd,
           id->orig_id = NULL;
 
           oldnewmap_insert(fd->libmap, id_bhead->old, id, id_bhead->code);
+          oldnewmap_insert(fd->libmap, id, id, id_bhead->code);
 
           ListBase *new_lb = which_libbase(main, idcode);
           BLI_remlink(old_lb, id);
@@ -9492,6 +9494,15 @@ static BHead *read_libblock(FileData *fd,
       /* for ID_LINK_PLACEHOLDER check */
       oldnewmap_insert(fd->libmap, id_bhead->old, id, id_bhead->code);
 
+      if (fd->old_mainlist != NULL) {
+        Main *old_bmain = fd->old_mainlist->first;
+        ListBase *old_lb = which_libbase(old_bmain, idcode);
+        ID *id_old;
+        if ((id_old = BLI_findstring(old_lb, id->name, offsetof(ID, name))) != NULL) {
+          oldnewmap_insert(fd->libmap, id_old, id, id_bhead->code);
+        }
+      }
+
       BLI_addtail(lb, id);
     }
     else {



More information about the Bf-blender-cvs mailing list