diff options
Diffstat (limited to 'source/blender/blenkernel/intern/undo_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/undo_system.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 14dd286a315..e524bd254bb 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -140,7 +140,7 @@ static void undosys_id_ref_store(void *UNUSED(user_data), UndoRefID *id_ref) static void undosys_id_ref_resolve(void *user_data, UndoRefID *id_ref) { - /* Note: we could optimize this, + /* NOTE: we could optimize this, * for now it's not too bad since it only runs when we access undo! */ Main *bmain = user_data; ListBase *lb = which_libbase(bmain, GS(id_ref->name)); @@ -717,11 +717,31 @@ eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack, } } - BLI_assert(!"Target undo step not found, this should not happen and may indicate an undo stack corruption"); + BLI_assert_msg(0, + "Target undo step not found, this should not happen and may indicate an undo " + "stack corruption"); return STEP_INVALID; } /** + * When reading undo steps for undo/redo, + * some extra checks are needed when so the correct undo step is decoded. + */ +static UndoStep *undosys_step_iter_first(UndoStep *us_reference, const eUndoStepDir undo_dir) +{ + if (us_reference->type->flags & UNDOTYPE_FLAG_DECODE_ACTIVE_STEP) { + /* Reading this step means an undo action reads undo twice. + * This should be avoided where possible, however some undo systems require it. + * + * Redo skips the current state as this represents the currently loaded state. */ + return (undo_dir == -1) ? us_reference : us_reference->next; + } + + /* Typical case, skip reading the current undo step. */ + return (undo_dir == -1) ? us_reference->prev : us_reference->next; +} + +/** * Undo/Redo until the given `us_target` step becomes the active (currently loaded) one. * * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the @@ -786,15 +806,10 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, us_target->type->name, undo_dir); - /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), from - * given reference step. - * - * NOTE: Unlike with redo case, where we can expect current active step to fully reflect current - * data status, in undo case we also do reload the active step. - * FIXME: this feels weak, and should probably not be actually needed? Or should also be done in - * redo case? */ + /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), + * from given reference step. */ bool is_processing_extra_skipped_steps = false; - for (UndoStep *us_iter = (undo_dir == -1) ? us_reference : us_reference->next; us_iter != NULL; + for (UndoStep *us_iter = undosys_step_iter_first(us_reference, undo_dir); us_iter != NULL; us_iter = (undo_dir == -1) ? us_iter->prev : us_iter->next) { BLI_assert(us_iter != NULL); |