Undo: support implicit-sharing in memfile undo step #106903

Merged
Jacques Lucke merged 78 commits from JacquesLucke/blender:implicit-sharing-undo into main 2024-02-29 17:15:09 +01:00
4 changed files with 39 additions and 24 deletions
Showing only changes of commit e9c40b8ce8 - Show all commits

View File

@ -129,6 +129,7 @@ void ED_undosys_type_free();
/* `memfile_undo.cc` */
MemFile *ED_undosys_stack_memfile_get_if_active(UndoStack *ustack);
/**
* If the last undo step is a memfile one, find the first #MemFileChunk matching given ID
* (using its session UUID), and tag it as "changed in the future".

View File

@ -345,6 +345,27 @@ void ED_memfile_undosys_type(UndoType *ut)
/** \name Utilities
* \{ */
/**
* Ideally we wouldn't need to export global undo internals,
* there are some cases where it's needed though.
*/
static MemFile *ed_undosys_step_get_memfile(UndoStep *us_p)
{
MemFileUndoStep *us = (MemFileUndoStep *)us_p;
return &us->data->memfile;
}
MemFile *ED_undosys_stack_memfile_get_if_active(UndoStack *ustack)
{
if (!ustack->step_active) {
return nullptr;
}
if (ustack->step_active->type != BKE_UNDOSYS_TYPE_MEMFILE) {
return nullptr;
}
return ed_undosys_step_get_memfile(ustack->step_active);
}
void ED_undosys_stack_memfile_id_changed_tag(UndoStack *ustack, ID *id)
{
UndoStep *us = ustack->step_active;

View File

@ -2115,9 +2115,12 @@ static bool wm_autosave_write_try(Main *bmain, wmWindowManager *wm)
wm_autosave_location(filepath);
if (MemFile *memfile = ED_undosys_stack_memfile_get_if_active(wm->undo_stack)) {
/* Fast save of last undo-buffer, now with UI. */
BLO_memfile_write_file(memfile, filepath);
/* Technically, we could always just save here, but that would cause performance regressions
* compared to when the #MemFile undo step was used for saving undo-steps. So for now just skip
* auto-save when we are in a mode where auto-save wouldn't have worked previously anyway. This
* check can be removed once the performance regressions have been solved. */
if (ED_undosys_stack_memfile_get_if_active(wm->undo_stack) != nullptr) {
WM_autosave_write(wm, bmain);
return true;
}
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
@ -2184,17 +2187,14 @@ void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer * /*wt*/)
{
wm_autosave_timer_end(wm);
/* Time to wait until the next attempt to autosave if it is disabled right now. */
const double try_again_time_step = 0.01;
/* If a modal operator is running, don't autosave because we might not be in
* a valid state to save. */
* a valid state to save. But try again in 10ms. */
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
LISTBASE_FOREACH (wmEventHandler *, handler_base, &win->modalhandlers) {
if (handler_base->type == WM_HANDLER_TYPE_OP) {
wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
if (handler->op) {
wm_autosave_timer_begin_ex(wm, try_again_time_step);
wm_autosave_timer_begin_ex(wm, 0.01);
return;
}
}

View File

@ -471,26 +471,19 @@ void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_
/* NOTE: same code copied in `wm_files.cc`. */
if (C && wm) {
if (do_user_exit_actions) {
/* save the undo state as quit.blend */
/* Save quit.blend. */
Main *bmain = CTX_data_main(C);
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
MemFile *undo_memfile = wm->undo_stack ?
ED_undosys_stack_memfile_get_if_active(wm->undo_stack) :
nullptr;
/* When true, the `undo_memfile` doesn't contain all information necessary
* for writing and up to date blend file. */
const bool is_memfile_outdated = ED_editors_flush_edits(bmain);
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
if (undo_memfile && !is_memfile_outdated) {
BLO_memfile_write_file(undo_memfile, filepath);
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
ED_editors_flush_edits(bmain);
BlendFileWriteParams blend_file_write_params{};
if (BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr)) {
printf("Saved session recovery to \"%s\"\n", filepath);
}
else {
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
BlendFileWriteParams blend_file_write_params{};
BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr);
}
printf("Saved session recovery to \"%s\"\n", filepath);
}
WM_jobs_kill_all(wm);