diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-01-30 12:44:15 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-01-30 12:44:15 +0300 |
commit | fbfe360cb13df5a6b47a86bf4cabd16e3bd92262 (patch) | |
tree | 14e86dca0250350c95eba472f56a916010b11b0d /source/blender/blenkernel/intern/undo_system.c | |
parent | a1ae04d15a9faaa9b4dc59e8a5bec02a7c69b255 (diff) |
Fix T60974: Dyntopo crash on undo after object deleted
Add the ability for undo steps to request memfile undo step added after
them, useful for mode switching, where we need the data to exist for
undo to enter the mode.
Diffstat (limited to 'source/blender/blenkernel/intern/undo_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/undo_system.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 7709b602179..d16f0569a57 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -512,7 +512,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char if (ut->step_foreach_ID_ref != NULL) { Main *bmain = G.main; if (bmain->is_memfile_undo_written == false) { - const char *name_internal = "MemFile Internal"; + const char *name_internal = "MemFile Internal (pre)"; /* Don't let 'step_init' cause issues when adding memfile undo step. */ void *step_init = ustack->step_init; ustack->step_init = NULL; @@ -531,25 +531,43 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char } #endif - UndoStep *us = ustack->step_init ? ustack->step_init : MEM_callocN(ut->step_size, __func__); - ustack->step_init = NULL; - if (us->name[0] == '\0') { - BLI_strncpy(us->name, name, sizeof(us->name)); - } - us->type = ut; - /* initialized, not added yet. */ + bool use_memfile_step = false; + { + UndoStep *us = ustack->step_init ? ustack->step_init : MEM_callocN(ut->step_size, __func__); + ustack->step_init = NULL; + if (us->name[0] == '\0') { + BLI_strncpy(us->name, name, sizeof(us->name)); + } + us->type = ut; + /* initialized, not added yet. */ - if (undosys_step_encode(C, ustack, us)) { + if (!undosys_step_encode(C, ustack, us)) { + MEM_freeN(us); + undosys_stack_validate(ustack, true); + return false; + } ustack->step_active = us; BLI_addtail(&ustack->steps, us); - undosys_stack_validate(ustack, true); - return true; + use_memfile_step = us->use_memfile_step; } - else { - MEM_freeN(us); - undosys_stack_validate(ustack, true); - return false; + + if (use_memfile_step) { + Main *bmain = G.main; + const char *name_internal = "MemFile Internal (post)"; + const bool ok = undosys_stack_push_main(ustack, name_internal, bmain); + if (ok) { + UndoStep *us = ustack->steps.last; + BLI_assert(STREQ(us->name, name_internal)); + us->skip = true; +#ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER + ustack->step_active_memfile = us; +#endif + ustack->step_active = us; + } } + + undosys_stack_validate(ustack, true); + return true; } bool BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name) |