Page MenuHome
Paste P1044

Fix T66325 (store mem-file undo steps from evaluated state)
ActivePublic

Authored by Campbell Barton (campbellbarton) on Jul 19 2019, 8:07 AM.
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index 50c29c456d1..aa90fe2cef5 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -65,6 +65,10 @@ typedef struct UndoStack {
* That is done once end is called.
*/
struct UndoStep *step_init;
+
+ /** Prepare undo step to add after evaluation. */
+ const struct UndoType *deferred_init_type;
+ char deferred_init_name[64];
} UndoStack;
typedef struct UndoStep {
@@ -187,6 +191,8 @@ UndoStep *BKE_undosys_step_same_type_prev(UndoStep *us);
UndoType *BKE_undosys_type_append(void (*undosys_fn)(UndoType *));
void BKE_undosys_type_free_all(void);
+const UndoType *BKE_undosys_type_from_context(struct bContext *C);
+
/* ID Accessor */
#if 0 /* functionality is only used internally for now. */
void BKE_undosys_foreach_ID_ref(UndoStack *ustack,
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 2d0a482d223..ff35ae24546 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -106,7 +106,7 @@ const UndoType *BKE_UNDOSYS_TYPE_TEXT = NULL;
static ListBase g_undo_types = {NULL, NULL};
-static const UndoType *BKE_undosys_type_from_context(bContext *C)
+const UndoType *BKE_undosys_type_from_context(bContext *C)
{
for (const UndoType *ut = g_undo_types.first; ut; ut = ut->next) {
/* No poll means we don't check context. */
diff --git a/source/blender/editors/include/ED_undo.h b/source/blender/editors/include/ED_undo.h
index fa2630ba726..e44f27062f1 100644
--- a/source/blender/editors/include/ED_undo.h
+++ b/source/blender/editors/include/ED_undo.h
@@ -32,6 +32,7 @@ struct wmOperator;
struct wmOperatorType;
/* undo.c */
+void ED_undo_push_deferred_eval(struct bContext *C);
void ED_undo_push(struct bContext *C, const char *str);
void ED_undo_push_op(struct bContext *C, struct wmOperator *op);
void ED_undo_grouped_push(struct bContext *C, const char *str);
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 183e140169d..16ca42ed307 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
#include "BLI_listbase.h"
+#include "BLI_string.h"
#include "BLT_translation.h"
@@ -75,6 +76,43 @@ static CLG_LogRef LOG = {"ed.undo"};
* Non-operator undo editor functions.
* \{ */
+void ED_undo_push_deferred_eval(bContext *C)
+{
+ UndoStack *ustack = ED_undo_stack_get();
+ if (ustack) {
+ const UndoType *ut = ustack->deferred_init_type;
+ char *name = ustack->deferred_init_name;
+ if (name[0]) {
+ BKE_undosys_step_push_with_type(ustack, C, name, ut);
+ name[0] = '\0';
+ }
+ }
+}
+
+/**
+ * Wrapper for #BKE_undosys_step_push which defers mem-file undo steps,
+ * since they need to be updated for animation edits, see: T66325.
+ */
+static void bke_undosys_step_push_deferred_wrapper(UndoStack *ustack, bContext *C, const char *str)
+{
+ /* Call now in-case we didn't call during event-loop. */
+ ED_undo_push_deferred_eval(C);
+
+ if (ustack->step_init) {
+ BKE_undosys_step_push(ustack, C, str);
+ }
+ else {
+ const UndoType *ut = BKE_undosys_type_from_context(C);
+ if (ut == BKE_UNDOSYS_TYPE_MEMFILE) {
+ ustack->deferred_init_type = ut;
+ STRNCPY(ustack->deferred_init_name, str);
+ }
+ else {
+ BKE_undosys_step_push_with_type(ustack, C, str, ut);
+ }
+ }
+}
+
void ED_undo_push(bContext *C, const char *str)
{
CLOG_INFO(&LOG, 1, "name='%s'", str);
@@ -92,7 +130,12 @@ void ED_undo_push(bContext *C, const char *str)
BKE_undosys_stack_limit_steps_and_memory(wm->undo_stack, steps - 1, 0);
}
- BKE_undosys_step_push(wm->undo_stack, C, str);
+ if (1) {
+ bke_undosys_step_push_deferred_wrapper(wm->undo_stack, C, str);
+ }
+ else {
+ BKE_undosys_step_push(wm->undo_stack, C, str);
+ }
if (U.undomemory != 0) {
const size_t memory_limit = (size_t)U.undomemory * 1024 * 1024;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 76cb78b1e04..295d5525934 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -395,6 +395,9 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C)
wm_event_do_depsgraph(C, false);
CTX_wm_window_set(C, NULL);
+
+ /* Support adding undo steps from the evaluated result. */
+ ED_undo_push_deferred_eval(C);
}
/* called in mainloop */

Event Timeline

  • Wrapper for #BKE_undosys_step_push which defers mem-file undo steps,
  • since they need to be updated for animation edits, see: T66325.

This is a handbook example of useless comments which doesn't explain why this is all needed. I can not gain any knowledge from this.
The report also doesn't add anything in this regard.

The issue in the report is explained here - T66325#726891

This is mainly explanation of a specific solution.