Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / blender_undo.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup bke
19  *
20  * Blend file undo (known as 'Global Undo').
21  * DNA level diffing for undo.
22  */
23
24 #ifndef _WIN32
25 #  include <unistd.h>  // for read close
26 #else
27 #  include <io.h>  // for open close read
28 #endif
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stddef.h>
33 #include <string.h>
34 #include <fcntl.h> /* for open */
35 #include <errno.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_scene_types.h"
40
41 #include "BLI_path_util.h"
42 #include "BLI_string.h"
43 #include "BLI_utildefines.h"
44
45 #include "BKE_appdir.h"
46 #include "BKE_blender_undo.h" /* own include */
47 #include "BKE_blendfile.h"
48 #include "BKE_context.h"
49 #include "BKE_global.h"
50 #include "BKE_main.h"
51
52 #include "BLO_undofile.h"
53 #include "BLO_readfile.h"
54 #include "BLO_writefile.h"
55
56 #include "DEG_depsgraph.h"
57
58 /* -------------------------------------------------------------------- */
59 /** \name Global Undo
60  * \{ */
61
62 #define UNDO_DISK 0
63
64 bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
65 {
66   Main *bmain = CTX_data_main(C);
67   char mainstr[sizeof(bmain->name)];
68   int success = 0, fileflags;
69
70   BLI_strncpy(mainstr, BKE_main_blendfile_path(bmain), sizeof(mainstr)); /* temporal store */
71
72   fileflags = G.fileflags;
73   G.fileflags |= G_FILE_NO_UI;
74
75   if (UNDO_DISK) {
76     success = (BKE_blendfile_read(C, mfu->filename, NULL, 0) != BKE_BLENDFILE_READ_FAIL);
77   }
78   else {
79     success = BKE_blendfile_read_from_memfile(
80         C, &mfu->memfile, &(const struct BlendFileReadParams){0}, NULL);
81   }
82
83   /* Restore, bmain has been re-allocated. */
84   bmain = CTX_data_main(C);
85   BLI_strncpy(bmain->name, mainstr, sizeof(bmain->name));
86   G.fileflags = fileflags;
87
88   if (success) {
89     /* important not to update time here, else non keyed transforms are lost */
90     DEG_on_visible_update(bmain, false);
91   }
92
93   return success;
94 }
95
96 MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev)
97 {
98   MemFileUndoData *mfu = MEM_callocN(sizeof(MemFileUndoData), __func__);
99
100   /* disk save version */
101   if (UNDO_DISK) {
102     static int counter = 0;
103     char filename[FILE_MAX];
104     char numstr[32];
105     int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */
106
107     /* Calculate current filename. */
108     counter++;
109     counter = counter % U.undosteps;
110
111     BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
112     BLI_make_file_string("/", filename, BKE_tempdir_session(), numstr);
113
114     /* success = */ /* UNUSED */ BLO_write_file(bmain, filename, fileflags, NULL, NULL);
115
116     BLI_strncpy(mfu->filename, filename, sizeof(mfu->filename));
117   }
118   else {
119     MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : NULL;
120     /* success = */ /* UNUSED */ BLO_write_file_mem(bmain, prevfile, &mfu->memfile, G.fileflags);
121     mfu->undo_size = mfu->memfile.size;
122   }
123
124   bmain->is_memfile_undo_written = true;
125
126   return mfu;
127 }
128
129 void BKE_memfile_undo_free(MemFileUndoData *mfu)
130 {
131   BLO_memfile_free(&mfu->memfile);
132   MEM_freeN(mfu);
133 }
134
135 /** \} */