[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58020] branches/soc-2013-ui_replay/source /blender: Keeps the operator stack synchronised with the undo stack so that the redo panel displays the right operator after an undo .

Vincent Akkermans vincent at ack-err.net
Fri Jul 5 15:10:54 CEST 2013


Revision: 58020
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58020
Author:   ack-err
Date:     2013-07-05 13:10:53 +0000 (Fri, 05 Jul 2013)
Log Message:
-----------
Keeps the operator stack synchronised with the undo stack so that the redo panel displays the right operator after an undo.

N.B. This is an updated version of patch #35059 in the tracker, which had a nasty bug in it still.

This patch aims to introduce functionality that keeps the two undo stacks (object mode, and edit mode) synchronised with the operator stack in the window manager. This allows for the operator redo panel to be initialised to the last operator that was performed to arrive at the current state after undos and redos are performed. This is achieved by keeping pointers to the operators in the UndoElem structs and rebuilding the wmWindowManager's operator stack after each undo or redo.

The changes throughout the code aim to achieve that a) wmOperator structs are passed to the undo systems to be stored in the UndoElem structures (changes in undo_push_X functions), b) wmOperator structs that are referenced from UndoElem structs are only freed by the undo system, and that c) the operators that are repeated instead of redone (repeat last, repeat from history) are copied rather than moved to the back of the operator stack.

Operators that have a flag OPTYPE_UNDO are registered in the undo system and the undo system is responsible only for these operators. Other operators are freed after application. Even though all OPTYPE_UNDO operators are registered in the undo system, only OPTYPE_REGISTER operators are included when generating the window managers operator stack.

N.B. The following changes aren't very nice and I would like to point them out explicitly.
- The undo system, which is part of blender's core, is now more strongly connected to window managing subsystem than before
- The UndoElem structs (one for object mode undo, and one for edit mode undo) are not exposed, but mapped to a third UndoElem in wm.c. This was done to avoid bringing too much WM logic into blender.c. Better but more involved solutions exist.

Further changes should include doing away with the operator stack entirely and use the undo system as the backend data model for it.

Modified Paths:
--------------
    branches/soc-2013-ui_replay/source/blender/blenkernel/BKE_blender.h
    branches/soc-2013-ui_replay/source/blender/blenkernel/intern/blender.c
    branches/soc-2013-ui_replay/source/blender/editors/armature/armature_utils.c
    branches/soc-2013-ui_replay/source/blender/editors/curve/editcurve.c
    branches/soc-2013-ui_replay/source/blender/editors/curve/editfont.c
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_armature.h
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_curve.h
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_mball.h
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_mesh.h
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_object.h
    branches/soc-2013-ui_replay/source/blender/editors/include/ED_util.h
    branches/soc-2013-ui_replay/source/blender/editors/mesh/editmesh_utils.c
    branches/soc-2013-ui_replay/source/blender/editors/metaball/mball_edit.c
    branches/soc-2013-ui_replay/source/blender/editors/object/object_lattice.c
    branches/soc-2013-ui_replay/source/blender/editors/screen/screen_ops.c
    branches/soc-2013-ui_replay/source/blender/editors/util/editmode_undo.c
    branches/soc-2013-ui_replay/source/blender/editors/util/undo.c
    branches/soc-2013-ui_replay/source/blender/editors/util/util_intern.h
    branches/soc-2013-ui_replay/source/blender/windowmanager/WM_api.h
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_event_system.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_files.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_init_exit.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_operators.c

Modified: branches/soc-2013-ui_replay/source/blender/blenkernel/BKE_blender.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/blenkernel/BKE_blender.h	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/blenkernel/BKE_blender.h	2013-07-05 13:10:53 UTC (rev 58020)
@@ -63,6 +63,7 @@
 struct Scene;
 struct Main;
 struct ID;
+struct wmOperator;
 
 int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports);
 
@@ -92,10 +93,12 @@
 
 /* global undo */
 extern void BKE_write_undo(struct bContext *C, const char *name);
+extern void BKE_write_undo_op(struct bContext *C, const char *name, struct wmOperator *op);
 extern void BKE_undo_step(struct bContext *C, int step);
+extern void BKE_undo_op(struct bContext *C, const struct wmOperator *op);
 extern void BKE_undo_name(struct bContext *C, const char *name);
 extern int BKE_undo_valid(const char *name);
-extern void BKE_reset_undo(void);
+extern void BKE_reset_undo(struct bContext *C);
 extern void BKE_undo_number(struct bContext *C, int nr);
 extern const char *BKE_undo_get_name(int nr, int *active);
 extern int BKE_undo_save_file(const char *filename);

Modified: branches/soc-2013-ui_replay/source/blender/blenkernel/intern/blender.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/blenkernel/intern/blender.c	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/blenkernel/intern/blender.c	2013-07-05 13:10:53 UTC (rev 58020)
@@ -558,8 +558,11 @@
 
 #define UNDO_DISK   0
 
+/* N.B. the pointer to the wmOperator needs to be third so that it 
+ * maps correctly to the UndoElem in wm.c. This is far from pretty. */
 typedef struct UndoElem {
 	struct UndoElem *next, *prev;
+	wmOperator * op;
 	char str[FILE_MAX];
 	char name[BKE_UNDO_STR_MAX];
 	MemFile memfile;
@@ -592,6 +595,9 @@
 	BLI_strncpy(G.main->name, mainstr, sizeof(G.main->name)); /* restore */
 	G.fileflags = fileflags;
 
+	ListBase included_ops = {undobase.first, uel};
+	WM_operator_build_stack(C, &included_ops, true);
+
 	if (success) {
 		/* important not to update time here, else non keyed tranforms are lost */
 		DAG_on_visible_update(G.main, FALSE);
@@ -600,13 +606,18 @@
 	return success;
 }
 
-/* name can be a dynamic string */
 void BKE_write_undo(bContext *C, const char *name)
 {
+	BKE_write_undo_op(C, name, NULL);
+}
+
+/* name can be a dynamic string */
+void BKE_write_undo_op(bContext *C, const char *name, wmOperator *op)
+{
 	uintptr_t maxmem, totmem, memused;
 	int nr /*, success */ /* UNUSED */;
 	UndoElem *uel;
-	
+
 	if ((U.uiflag & USER_GLOBALUNDO) == 0) {
 		return;
 	}
@@ -620,6 +631,10 @@
 		uel = undobase.last;
 		BLI_remlink(&undobase, uel);
 		BLO_free_memfile(&uel->memfile);
+		/* Don't remove the op if it is a repeat, and the
+		 * uel->op is the same as the function's argument op. */
+		if(uel->op && uel->op != op)
+			WM_operator_free(uel->op);
 		MEM_freeN(uel);
 	}
 	
@@ -627,6 +642,7 @@
 	curundo = uel = MEM_callocN(sizeof(UndoElem), "undo file");
 	BLI_strncpy(uel->name, name, sizeof(uel->name));
 	BLI_addtail(&undobase, uel);
+	uel->op = op;
 	
 	/* and limit amount to the maximum */
 	nr = 0;
@@ -642,6 +658,8 @@
 			BLI_remlink(&undobase, first);
 			/* the merge is because of compression */
 			BLO_merge_memfile(&first->memfile, &first->next->memfile);
+			if(first->op)
+				WM_operator_free(first->op);
 			MEM_freeN(first);
 		}
 	}
@@ -697,10 +715,14 @@
 				BLI_remlink(&undobase, first);
 				/* the merge is because of compression */
 				BLO_merge_memfile(&first->memfile, &first->next->memfile);
+				if(first->op)
+					WM_operator_free(first->op);
 				MEM_freeN(first);
 			}
 		}
 	}
+	
+	WM_operator_build_stack(C, &undobase, true);
 }
 
 /* 1 = an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
@@ -735,18 +757,22 @@
 	}
 }
 
-void BKE_reset_undo(void)
+void BKE_reset_undo(bContext *C)
 {
 	UndoElem *uel;
 	
 	uel = undobase.first;
 	while (uel) {
 		BLO_free_memfile(&uel->memfile);
+		if(uel->op)
+			WM_operator_free(uel->op);
 		uel = uel->next;
 	}
 	
 	BLI_freelistN(&undobase);
 	curundo = NULL;
+
+	WM_operator_build_stack(C, &undobase, false);
 }
 
 /* based on index nr it does a restore */
@@ -756,17 +782,39 @@
 	BKE_undo_step(C, 0);
 }
 
-/* go back to the last occurance of name in stack */
-void BKE_undo_name(bContext *C, const char *name)
+/* go back to the last occurance of the given name, or the 
+ * given operator */
+static void undo_op_name(bContext *C, const wmOperator *op, const char *name)
 {
-	UndoElem *uel = BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
-
+	ListBase included_ops;
+	included_ops.first = undobase.first;
+	included_ops.last = curundo ? curundo : undobase.last;
+	UndoElem *uel;
+	
+	if(op)
+		uel = BLI_findptr(&included_ops, op, offsetof(UndoElem, op));
+	else
+		uel = BLI_rfindstring(&included_ops, name, offsetof(UndoElem, name));
+	
 	if (uel && uel->prev) {
 		curundo = uel->prev;
 		BKE_undo_step(C, 0);
 	}
 }
 
+/* go back to the last occurance of name in stack */
+void BKE_undo_name(bContext *C, const char *name)
+{
+	undo_op_name(C, NULL, name);
+}
+
+
+/* go back to the last occurance of the given operator */
+void BKE_undo_op(bContext *C, const wmOperator *op)
+{
+	undo_op_name(C, op, NULL);
+}
+
 /* name optional */
 int BKE_undo_valid(const char *name)
 {

Modified: branches/soc-2013-ui_replay/source/blender/editors/armature/armature_utils.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/armature/armature_utils.c	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/editors/armature/armature_utils.c	2013-07-05 13:10:53 UTC (rev 58020)
@@ -29,6 +29,7 @@
 
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -673,8 +674,8 @@
 }
 
 /* and this is all the undo system needs to know */
-void undo_push_armature(bContext *C, const char *name)
+void undo_push_armature(bContext *C, const char *name, wmOperator *op)
 {
 	// XXX solve getdata()
-	undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
+	undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL, op);
 }

Modified: branches/soc-2013-ui_replay/source/blender/editors/curve/editcurve.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/curve/editcurve.c	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/editors/curve/editcurve.c	2013-07-05 13:10:53 UTC (rev 58020)
@@ -7068,9 +7068,9 @@
 }
 
 /* and this is all the undo system needs to know */
-void undo_push_curve(bContext *C, const char *name)
+void undo_push_curve(bContext *C, const char *name, wmOperator *op)
 {
-	undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
+	undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL, op);
 }
 
 void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)

Modified: branches/soc-2013-ui_replay/source/blender/editors/curve/editfont.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/curve/editfont.c	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/editors/curve/editfont.c	2013-07-05 13:10:53 UTC (rev 58020)
@@ -1782,7 +1782,7 @@
 }
 
 /* and this is all the undo system needs to know */
-void undo_push_font(bContext *C, const char *name)
+void undo_push_font(bContext *C, const char *name, wmOperator *op)
 {
-	undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
+	undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL, op);
 }

Modified: branches/soc-2013-ui_replay/source/blender/editors/include/ED_armature.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/include/ED_armature.h	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/editors/include/ED_armature.h	2013-07-05 13:10:53 UTC (rev 58020)
@@ -151,7 +151,7 @@
 void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */
 void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep);
 
-void undo_push_armature(struct bContext *C, const char *name);
+void undo_push_armature(struct bContext *C, const char *name, struct wmOperator *op);
 
 /* poseobject.c */
 void ED_armature_exit_posemode(struct bContext *C, struct Base *base);

Modified: branches/soc-2013-ui_replay/source/blender/editors/include/ED_curve.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/include/ED_curve.h	2013-07-05 09:34:17 UTC (rev 58019)
+++ branches/soc-2013-ui_replay/source/blender/editors/include/ED_curve.h	2013-07-05 13:10:53 UTC (rev 58020)
@@ -56,7 +56,7 @@
 void CU_select_swap(struct Object *obedit);
 
 
-void    undo_push_curve(struct bContext *C, const char *name);
+void    undo_push_curve(struct bContext *C, const char *name, struct wmOperator *op);
 ListBase *object_editcurve_get(struct Object *ob);
 
 void    load_editNurb(struct Object *obedit);
@@ -72,7 +72,7 @@
 int     join_curve_exec(struct bContext *C, struct wmOperator *op);
 
 /* editfont.h */
-void    undo_push_font(struct bContext *C, const char *name);
+void    undo_push_font(struct bContext *C, const char *name, struct wmOperator *op);
 void    make_editText(struct Object *obedit);
 void    load_editText(struct Object *obedit);
 void    free_editText(struct Object *obedit);

Modified: branches/soc-2013-ui_replay/source/blender/editors/include/ED_mball.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/include/ED_mball.h	2013-07-05 09:34:17 UTC (rev 58019)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list