Undo: support implicit-sharing in memfile undo step #106903
|
@ -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".
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue