Blender V4.3
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
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 <cstddef>
20#include <cstdio>
21#include <cstdlib>
22#include <cstring>
23#include <fcntl.h> /* for open */
24
25#include "MEM_guardedalloc.h"
26
27#include "DNA_scene_types.h"
28
29#include "BLI_path_utils.hh"
30#include "BLI_string.h"
31#include "BLI_utildefines.h"
32
33#include "BKE_appdir.hh"
34#include "BKE_blender_undo.hh" /* own include */
35#include "BKE_blendfile.hh"
36#include "BKE_context.hh"
37#include "BKE_global.hh"
38#include "BKE_main.hh"
39#include "BKE_undo_system.hh"
40
41#include "BLO_readfile.hh"
42#include "BLO_undofile.hh"
43#include "BLO_writefile.hh"
44
45#include "DEG_depsgraph.hh"
46
47/* -------------------------------------------------------------------- */
51#define UNDO_DISK 0
52
54 const eUndoStepDir undo_direction,
55 const bool use_old_bmain_data,
56 bContext *C)
57{
58 Main *bmain = CTX_data_main(C);
59 char mainstr[sizeof(bmain->filepath)];
60 int success = 0, fileflags;
61
62 STRNCPY(mainstr, BKE_main_blendfile_path(bmain)); /* temporal store */
63
64 fileflags = G.fileflags;
65 G.fileflags |= G_FILE_NO_UI;
66
67 if (UNDO_DISK) {
69 BlendFileReadReport bf_reports{};
70 BlendFileData *bfd = BKE_blendfile_read(mfu->filepath, &params, &bf_reports);
71 if (bfd != nullptr) {
72 BKE_blendfile_read_setup_undo(C, bfd, &params, &bf_reports);
73 success = true;
74 }
75 }
76 else {
78 params.undo_direction = undo_direction;
79 if (!use_old_bmain_data) {
81 }
82 BlendFileReadReport blend_file_read_report{};
83 BlendFileData *bfd = BKE_blendfile_read_from_memfile(bmain, &mfu->memfile, &params, nullptr);
84 if (bfd != nullptr) {
85 BKE_blendfile_read_setup_undo(C, bfd, &params, &blend_file_read_report);
86 success = true;
87 }
88 }
89
90 /* Restore, bmain has been re-allocated. */
91 bmain = CTX_data_main(C);
92 STRNCPY(bmain->filepath, mainstr);
93 G.fileflags = fileflags;
94
95 if (success) {
96 /* important not to update time here, else non keyed transforms are lost */
97 DEG_tag_on_visible_update(bmain, false);
98 }
99
100 return success;
101}
102
104{
105 MemFileUndoData *mfu = MEM_cnew<MemFileUndoData>(__func__);
106
107 /* This flag used to be set because the undo step was written as #BLENDER_QUIT_FILE. It's not
108 * clear whether there are still good reasons to keep it. Undo can also be thought of as a kind
109 * of recovery, so better keep it for now. */
110 const int fileflags = G.fileflags | G_FILE_RECOVER_WRITE;
111
112 /* disk save version */
113 if (UNDO_DISK) {
114 static int counter = 0;
115 char filepath[FILE_MAX];
116 char numstr[32];
117
118 /* Calculate current filepath. */
119 counter++;
120 counter = counter % U.undosteps;
121
122 SNPRINTF(numstr, "%d.blend", counter);
123 BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), numstr);
124
125 const BlendFileWriteParams blend_file_write_params{};
126 /* success = */ /* UNUSED */ BLO_write_file(
127 bmain, filepath, fileflags, &blend_file_write_params, nullptr);
128
129 STRNCPY(mfu->filepath, filepath);
130 }
131 else {
132 MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : nullptr;
133 if (prevfile) {
134 BLO_memfile_clear_future(prevfile);
135 }
136 /* success = */ /* UNUSED */ BLO_write_file_mem(bmain, prevfile, &mfu->memfile, fileflags);
137 mfu->undo_size = mfu->memfile.size;
138 }
139
140 bmain->is_memfile_undo_written = true;
141
142 return mfu;
143}
144
146{
148 MEM_freeN(mfu);
149}
150
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:832
eUndoStepDir
#define FILE_MAX
#define BLI_path_join(...)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
external readfile function prototypes.
@ BLO_READ_SKIP_UNDO_OLD_MAIN
void BLO_memfile_clear_future(MemFile *memfile)
Definition undofile.cc:93
void BLO_memfile_free(MemFile *memfile)
Definition undofile.cc:41
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)
Read Guarded memory(de)allocation.
#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)
unsigned int U
Definition btGjkEpa3.h:78
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
char filepath[1024]
Definition BKE_main.hh:136
bool is_memfile_undo_written
Definition BKE_main.hh:160
char filepath[1024]
size_t size
void * BKE_tempdir_session
Definition stubs.c:38