Blender V5.0
blender_undo.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11
12#ifndef _WIN32
13# include <unistd.h> /* for read close */
14#else
15# include <io.h> /* for open close read */
16#endif
17
18#include <cerrno>
19#include <cstdio>
20#include <cstdlib>
21#include <cstring>
22#include <fcntl.h> /* for open */
23
24#include "DNA_userdef_types.h"
25
26#include "BLI_path_utils.hh"
27#include "BLI_string.h"
28
29#include "BKE_appdir.hh"
30#include "BKE_blender_undo.hh" /* own include */
31#include "BKE_blendfile.hh"
32#include "BKE_context.hh"
33#include "BKE_global.hh"
34#include "BKE_main.hh"
35#include "BKE_undo_system.hh"
36
37#include "BLO_readfile.hh"
38#include "BLO_undofile.hh"
39#include "BLO_writefile.hh"
40
41#include "DEG_depsgraph.hh"
42
43/* -------------------------------------------------------------------- */
46
47#define UNDO_DISK 0
48
50 const eUndoStepDir undo_direction,
51 const bool use_old_bmain_data,
52 bContext *C)
53{
54 Main *bmain = CTX_data_main(C);
55 char mainstr[sizeof(bmain->filepath)];
56 int success = 0, fileflags;
57
58 STRNCPY(mainstr, BKE_main_blendfile_path(bmain)); /* temporal store */
59
60 fileflags = G.fileflags;
61 G.fileflags |= G_FILE_NO_UI;
62
63 if (UNDO_DISK) {
65 BlendFileReadReport bf_reports{};
66 BlendFileData *bfd = BKE_blendfile_read(mfu->filepath, &params, &bf_reports);
67 if (bfd != nullptr) {
68 BKE_blendfile_read_setup_undo(C, bfd, &params, &bf_reports);
69 success = true;
70 }
71 }
72 else {
74 params.undo_direction = undo_direction;
75 if (!use_old_bmain_data) {
77 }
78 BlendFileReadReport blend_file_read_report{};
79 BlendFileData *bfd = BKE_blendfile_read_from_memfile(bmain, &mfu->memfile, &params, nullptr);
80 if (bfd != nullptr) {
81 BKE_blendfile_read_setup_undo(C, bfd, &params, &blend_file_read_report);
82 success = true;
83 }
84 }
85
86 /* Restore, bmain has been re-allocated. */
87 bmain = CTX_data_main(C);
88 STRNCPY(bmain->filepath, mainstr);
89 G.fileflags = fileflags;
90
91 if (success) {
92 /* important not to update time here, else non keyed transforms are lost */
93 DEG_tag_on_visible_update(bmain, false);
94 }
95
96 return success;
97}
98
100{
102
103 /* This flag used to be set because the undo step was written as #BLENDER_QUIT_FILE. It's not
104 * clear whether there are still good reasons to keep it. Undo can also be thought of as a kind
105 * of recovery, so better keep it for now. */
106 const int fileflags = G.fileflags | G_FILE_RECOVER_WRITE;
107
108 /* disk save version */
109 if (UNDO_DISK) {
110 static int counter = 0;
111 char filepath[FILE_MAX];
112 char numstr[32];
113
114 /* Calculate current filepath. */
115 counter++;
116 counter = counter % U.undosteps;
117
118 SNPRINTF(numstr, "%d.blend", counter);
119 BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), numstr);
120
121 const BlendFileWriteParams blend_file_write_params{};
122 /* success = */ /* UNUSED */ BLO_write_file(
123 bmain, filepath, fileflags, &blend_file_write_params, nullptr);
124
125 STRNCPY(mfu->filepath, filepath);
126 }
127 else {
128 MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : nullptr;
129 if (prevfile) {
130 BLO_memfile_clear_future(prevfile);
131 }
132 /* success = */ /* UNUSED */ BLO_write_file_mem(bmain, prevfile, &mfu->memfile, fileflags);
133 mfu->undo_size = mfu->memfile.size;
134 }
135
136 bmain->is_memfile_undo_written = true;
137
138 return mfu;
139}
140
142{
144 MEM_freeN(mfu);
145}
146
void BKE_blendfile_read_setup_undo(bContext *C, BlendFileData *bfd, const BlendFileReadParams *params, BlendFileReadReport *reports)
BlendFileData * BKE_blendfile_read_from_memfile(Main *bmain, MemFile *memfile, const BlendFileReadParams *params, ReportList *reports)
BlendFileData * BKE_blendfile_read(const char *filepath, const BlendFileReadParams *params, BlendFileReadReport *reports)
Main * CTX_data_main(const bContext *C)
@ G_FILE_RECOVER_WRITE
@ G_FILE_NO_UI
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:887
eUndoStepDir
#define FILE_MAX
#define BLI_path_join(...)
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:604
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
external readfile function prototypes.
@ BLO_READ_SKIP_UNDO_OLD_MAIN
void BLO_memfile_clear_future(MemFile *memfile)
Definition undofile.cc:90
void BLO_memfile_free(MemFile *memfile)
Definition undofile.cc:38
external writefile.cc function prototypes.
bool BLO_write_file(Main *mainvar, const char *filepath, int write_flags, const BlendFileWriteParams *params, ReportList *reports)
bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int write_flags)
void DEG_tag_on_visible_update(Main *bmain, bool do_time)
#define C
Definition RandGen.cpp:29
#define U
#define UNDO_DISK
MemFileUndoData * BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev)
void BKE_memfile_undo_free(MemFileUndoData *mfu)
bool BKE_memfile_undo_decode(MemFileUndoData *mfu, const eUndoStepDir undo_direction, const bool use_old_bmain_data, bContext *C)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
char filepath[1024]
Definition BKE_main.hh:179
bool is_memfile_undo_written
Definition BKE_main.hh:208
char filepath[1024]
size_t size
void * BKE_tempdir_session
Definition stubs.c:38