diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-02-05 06:24:11 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-02-06 03:52:04 +0300 |
commit | e535ff44ffd686def7aafec401acec657f5a614c (patch) | |
tree | 39910c4513dd223378f71af51730fae3a62ac3ae /source/blender/blenkernel | |
parent | 8996e26116f063ce28a9784899fc36d87f31dabe (diff) |
Undo System: remove accumulate/store modes
This complicated handling of undo steps in a generic way
especially switching between undo systems that stored data to ones
that accumulated changes.
Now each undo system must treat it's steps as check-point,
internally it can apply/rewind changes.
This commit also fixes projection paint where the object mode wasn't
following the undo steps.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_undo_system.h | 21 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/undo_system.c | 33 |
2 files changed, 20 insertions, 34 deletions
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h index 2b1c67f372b..15f4bac17a9 100644 --- a/source/blender/blenkernel/BKE_undo_system.h +++ b/source/blender/blenkernel/BKE_undo_system.h @@ -72,24 +72,11 @@ typedef struct UndoStep { bool skip; /** Some situations require the global state to be stored, edge cases when exiting modes. */ bool use_memfile_step; + /** For use by undo systems that accumulate changes (text editor, painting). */ + bool is_applied; /* Over alloc 'type->struct_size'. */ } UndoStep; -typedef enum eUndoTypeMode { - /** - * Each undo step stores a version of the state. - * This means we can simply load in a previous state at any time. - */ - BKE_UNDOTYPE_MODE_STORE = 1, - /** - * Each undo step is a series of edits. - * This means to change states we need to apply each edit. - * It also means the 'step_decode' callback needs to detect the difference between undo and redo. - * (Currently used for text edit and image & sculpt painting). - */ - BKE_UNDOTYPE_MODE_ACCUMULATE = 2, -} eUndoTypeMode; - typedef void (*UndoTypeForEachIDRefFn)(void *user_data, struct UndoRefID *id_ref); typedef struct UndoType { @@ -122,7 +109,6 @@ typedef struct UndoType { void (*step_foreach_ID_ref)(UndoStep *us, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data); - eUndoTypeMode mode; bool use_context; int step_size; @@ -136,6 +122,9 @@ extern const UndoType *BKE_UNDOSYS_TYPE_PARTICLE; extern const UndoType *BKE_UNDOSYS_TYPE_SCULPT; extern const UndoType *BKE_UNDOSYS_TYPE_TEXT; +#define BKE_UNDOSYS_TYPE_IS_MEMFILE_SKIP(ty) \ + ELEM(ty, BKE_UNDOSYS_TYPE_IMAGE) + UndoStack *BKE_undosys_stack_create(void); void BKE_undosys_stack_destroy(UndoStack *ustack); void BKE_undosys_stack_clear(UndoStack *ustack); diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index f56dd953283..b0836f822a6 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -337,7 +337,7 @@ void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain) void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C) { const UndoType *ut = BKE_undosys_type_from_context(C); - if ((ut != NULL) && (ut != BKE_UNDOSYS_TYPE_MEMFILE) && (ut->mode == BKE_UNDOTYPE_MODE_STORE)) { + if ((ut != NULL) && (ut != BKE_UNDOSYS_TYPE_MEMFILE)) { BKE_undosys_step_push_with_type(ustack, C, "original mode", ut); } } @@ -657,16 +657,17 @@ bool BKE_undosys_step_undo_with_data_ex( if (ustack->step_active) { UndoStep *us_iter = ustack->step_active; while (us_iter != us) { - if (us_iter->type->mode == BKE_UNDOTYPE_MODE_ACCUMULATE) { - undosys_step_decode(C, G_MAIN, ustack, us_iter, -1); - } + /* TODO: + * - skip successive steps that store the same data, eg: memfile steps. + * - or steps that include another steps data, eg: a memfile step includes text undo data. + */ + undosys_step_decode(C, G_MAIN, ustack, us_iter, -1); us_iter = us_iter->prev; } } - if (us->type->mode != BKE_UNDOTYPE_MODE_ACCUMULATE) { - undosys_step_decode(C, G_MAIN, ustack, us, -1); - } + undosys_step_decode(C, G_MAIN, ustack, us, -1); + ustack->step_active = us_prev; undosys_stack_validate(ustack, true); if (use_skip) { @@ -712,14 +713,11 @@ bool BKE_undosys_step_redo_with_data_ex( if (ustack->step_active && ustack->step_active->next) { UndoStep *us_iter = ustack->step_active->next; while (us_iter != us) { - if (us_iter->type->mode == BKE_UNDOTYPE_MODE_ACCUMULATE) { - undosys_step_decode(C, G_MAIN, ustack, us_iter, 1); - } + undosys_step_decode(C, G_MAIN, ustack, us_iter, 1); us_iter = us_iter->next; } } - /* Unlike undo, always redo accumulation state. */ undosys_step_decode(C, G_MAIN, ustack, us, 1); ustack->step_active = us_next; if (use_skip) { @@ -793,8 +791,6 @@ UndoType *BKE_undosys_type_append(void (*undosys_fn)(UndoType *)) undosys_fn(ut); - BLI_assert(ut->mode != 0); - BLI_addtail(&g_undo_types, ut); return ut; @@ -1010,14 +1006,15 @@ ID *BKE_undosys_ID_map_lookup_with_prev(const UndoIDPtrMap *map, ID *id_src, ID void BKE_undosys_print(UndoStack *ustack) { - printf("Undo %d Steps (A: active, M=memfile-active, S=skip)\n", + printf("Undo %d Steps (*: active, #=applied, M=memfile-active, S=skip)\n", BLI_listbase_count(&ustack->steps)); int index = 0; for (UndoStep *us = ustack->steps.first; us; us = us->next) { - printf("[%c%c%c] %3d type='%s', name='%s'\n", - (us == ustack->step_active) ? 'A' : '_', - (us == ustack->step_active_memfile) ? 'M' : '_', - us->skip ? 'S' : '_', + printf("[%c%c%c%c] %3d type='%s', name='%s'\n", + (us == ustack->step_active) ? '*' : ' ', + us->is_applied ? '#' : ' ', + (us == ustack->step_active_memfile) ? 'M' : ' ', + us->skip ? 'S' : ' ', index, us->type->name, us->name); |