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 { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs