[Bf-blender-cvs] [d726305d98d] undo-experiments: Fully WIP code.
Bastien Montagne
noreply at git.blender.org
Thu Nov 28 12:43:40 CET 2019
Commit: d726305d98db6ccfb1f3b4cd9b7b75540e606faa
Author: Bastien Montagne
Date: Thu Nov 28 12:40:38 2019 +0100
Branches: undo-experiments
https://developer.blender.org/rBd726305d98db6ccfb1f3b4cd9b7b75540e606faa
Fully WIP code.
Don't have proper solution yet for issue described in comment in
readfile.h, still investigating...
===================================================================
M source/blender/blenkernel/intern/undo_system.c
M source/blender/blenloader/intern/readblenentry.c
M source/blender/blenloader/intern/readfile.c
M source/blender/blenloader/intern/readfile.h
===================================================================
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index a068119b10b..eee07437aa7 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -192,11 +192,15 @@ static void undosys_step_decode(
/* Common case, we're already using the last memfile state. */
}
else {
+ GHash *depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain);
+
/* Load the previous memfile state so any ID's referenced in this
* undo step will be correctly resolved, see: T56163. */
undosys_step_decode(C, bmain, ustack, us_iter, dir, false);
/* May have been freed on memfile read. */
- bmain = G.main;
+ bmain = G_MAIN;
+
+ BKE_scene_undo_depsgraphs_restore(bmain, depsgraphs);
}
break;
}
@@ -675,10 +679,6 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
if (us != NULL) {
CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
- Main *bmain = CTX_data_main(C);
- GHash *depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain);
- bmain = NULL;
-
/* Handle accumulate steps. */
if (ustack->step_active) {
UndoStep *us_iter = ustack->step_active;
@@ -717,9 +717,6 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
} while ((us_active != us_iter) && (us_iter = us_iter->prev));
}
- bmain = CTX_data_main(C);
- BKE_scene_undo_depsgraphs_restore(bmain, depsgraphs);
-
return true;
}
return false;
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index a4b96c9e59c..dd6d43fc69f 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -398,8 +398,30 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
/* removed packed data from this trick - it's internal data that needs saves */
+ printf("BEFORE readfile:\n");
+ for (Collection *coll = oldmain->collections.first; coll != NULL; coll = coll->id.next) {
+ for (CollectionObject *cob = coll->gobject.first; cob != NULL; cob = cob->next) {
+ printf("\t%s: Collection %s (%p) has object %s\n",
+ __func__,
+ coll->id.name,
+ coll,
+ cob->ob->id.name);
+ }
+ }
+
bfd = blo_read_file_internal(fd, filename);
+ printf("AFTER readfile:\n");
+ for (Collection *coll = bfd->main->collections.first; coll != NULL; coll = coll->id.next) {
+ for (CollectionObject *cob = coll->gobject.first; cob != NULL; cob = cob->next) {
+ printf("\t%s: Collection %s (%p) has object %s\n",
+ __func__,
+ coll->id.name,
+ coll,
+ cob->ob->id.name);
+ }
+ }
+
/* ensures relinked light caches are not freed */
blo_end_scene_pointer_map(fd, oldmain);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 047f977a2b7..02dca6b4504 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1587,6 +1587,9 @@ void blo_filedata_free(FileData *fd)
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) {
oldnewmap_free(fd->libmap);
}
+ if (fd->libmap_undo) {
+ oldnewmap_free(fd->libmap_undo);
+ }
if (fd->bheadmap) {
MEM_freeN(fd->bheadmap);
}
@@ -1802,6 +1805,13 @@ static void *newpackedadr(FileData *fd, const void *adr)
/* only lib data */
static void *newlibadr(FileData *fd, const void *lib, const void *adr)
{
+ if (fd->memfile != NULL && fd->libmap_undo != NULL) {
+ void *ret = oldnewmap_liblookup(fd->libmap, adr, lib);
+ if (ret == NULL) {
+ ret = oldnewmap_liblookup(fd->libmap_undo, adr, lib);
+ }
+ return ret;
+ }
return oldnewmap_liblookup(fd->libmap, adr, lib);
}
@@ -6295,6 +6305,7 @@ static void lib_link_collection_data(FileData *fd, Library *lib, Collection *col
{
for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
cob_next = cob->next;
+ Object *ob_prev = cob->ob;
cob->ob = newlibadr_us(fd, lib, cob->ob);
if (cob->ob == NULL) {
@@ -9302,14 +9313,15 @@ static BHead *read_libblock(FileData *fd,
if (fd->are_memchunks_identical && !ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
BLI_assert(fd->memfile);
- Main *old_main = fd->old_mainlist->first;
- ID *old_id = NULL;
- if ((old_id = BKE_libblock_find_name(old_main, idcode, id->name + 2)) != NULL) {
- /* that would only match for basic undo step, redo and other history navigation cannot
- * guarantee this at all. */
- // BLI_assert(old_id == id_bhead->old);
+
+ /* Find the 'current' existing ID we want to reuse instead of the one we would read from
+ * the undo memfile. */
+ 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) {
MEM_freeN(id);
- id = old_id;
+ id = (ID *)id_bhead->old;
id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
id->lib = main->curlib;
@@ -9318,9 +9330,16 @@ static BHead *read_libblock(FileData *fd,
id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
id->orig_id = NULL;
+ if (GS(id->name) == ID_OB) {
+ printf("\t%s: Adding object to oldnewmap: old %p -> new %p (%s)\n",
+ __func__,
+ id_bhead->old,
+ id,
+ id->name);
+ }
oldnewmap_insert(fd->libmap, id_bhead->old, id, id_bhead->code);
- ListBase *old_lb = which_libbase(old_main, idcode);
+ ListBase *old_lb = which_libbase(old_bmain, idcode);
ListBase *new_lb = which_libbase(main, idcode);
BLI_remlink_safe(old_lb, id);
BLI_addtail(new_lb, id);
@@ -9341,6 +9360,13 @@ static BHead *read_libblock(FileData *fd,
lb = which_libbase(main, idcode);
if (lb) {
/* for ID_LINK_PLACEHOLDER check */
+ if (GS(id->name) == ID_OB) {
+ printf("\t%s: Adding object to oldnewmap: old %p -> new %p (%s)\n",
+ __func__,
+ id_bhead->old,
+ id,
+ id->name);
+ }
oldnewmap_insert(fd->libmap, id_bhead->old, id, id_bhead->code);
BLI_addtail(lb, id);
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 93715d01458..d94d10b3b63 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -113,6 +113,20 @@ typedef struct FileData {
struct OldNewMap *datamap;
struct OldNewMap *globmap;
struct OldNewMap *libmap;
+ /* We need a different mapping in undo case, when we are re-using some datablocks while getting
+ * new-from-file data for others, after the first step there is no way to tell where is that new
+ * ID from current, unchanged data (because we now have to deal with three different pointers
+ * for that new ID: the original one before any undo [stored in mem .blend file], the one after
+ * the first undo step [which is now used by other IDs from current bmain, that we want to
+ * re-use], and the new one from current undo step).
+ *
+ * `libmap` will only have the `original -> new` pointers, so we need to store the
+ * `from_previous_undostep -> new` pointers in another mapping.
+ *
+ * There is a little risk of collision here,
+ * will have to investigate wthere we can avoid that, or at the very least detect it and swicth
+ * back to a full proper read from memfile then... */
+ struct OldNewMap *libmap_undo;
struct OldNewMap *imamap;
struct OldNewMap *movieclipmap;
struct OldNewMap *scenemap;
More information about the Bf-blender-cvs
mailing list