Fix T60809: Crash undoing object rename in edit-mode
[blender.git] / source / blender / blenkernel / BKE_undo_system.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20 #ifndef __BKE_UNDO_SYSTEM_H__
21 #define __BKE_UNDO_SYSTEM_H__
22
23 /** \file BKE_undo_system.h
24  *  \ingroup bke
25  */
26
27 struct Main;
28 struct UndoStep;
29 struct bContext;
30
31 /* ID's */
32 struct Mesh;
33 struct Object;
34 struct Scene;
35 struct Text;
36
37 #include "DNA_ID.h"
38 #include "DNA_listBase.h"
39
40 typedef struct UndoRefID { struct ID *ptr; char name[MAX_ID_NAME]; } UndoRefID;
41 /* UndoRefID_Mesh & friends. */
42 #define UNDO_REF_ID_TYPE(ptr_ty) \
43         typedef struct UndoRefID_##ptr_ty { struct ptr_ty *ptr; char name[MAX_ID_NAME]; } UndoRefID_##ptr_ty
44 UNDO_REF_ID_TYPE(Mesh);
45 UNDO_REF_ID_TYPE(Object);
46 UNDO_REF_ID_TYPE(Scene);
47 UNDO_REF_ID_TYPE(Text);
48
49 typedef struct UndoStack {
50         ListBase         steps;
51         struct UndoStep *step_active;
52         /**
53          * The last memfile state read, used so we can be sure the names from the
54          * library state matches the state an undo step was written in.
55          */
56         struct UndoStep *step_active_memfile;
57
58         /**
59          * Some undo systems require begin/end, see: #UndoType.step_encode_init
60          *
61          * \note This is not included in the 'steps' list.
62          * That is done once end is called.
63          */
64         struct UndoStep *step_init;
65 } UndoStack;
66
67
68 typedef struct UndoStep {
69         struct UndoStep *next, *prev;
70         char name[64];
71         const struct UndoType *type;
72         /** Size in bytes of all data in step (not including the step). */
73         size_t data_size;
74         /** Users should never see this step (only use for internal consistency). */
75         bool skip;
76         /* Over alloc 'type->struct_size'. */
77 } UndoStep;
78
79 typedef enum eUndoTypeMode {
80         /**
81          * Each undo step stores a version of the state.
82          * This means we can simply load in a previous state at any time.
83          */
84         BKE_UNDOTYPE_MODE_STORE = 1,
85         /**
86          * Each undo step is a series of edits.
87          * This means to change states we need to apply each edit.
88          * It also means the 'step_decode' callback needs to detect the difference between undo and redo.
89          * (Currently used for text edit and image & sculpt painting).
90          */
91         BKE_UNDOTYPE_MODE_ACCUMULATE = 2,
92 } eUndoTypeMode;
93
94 typedef void (*UndoTypeForEachIDRefFn)(void *user_data, struct UndoRefID *id_ref);
95
96 typedef struct UndoType {
97         struct UndoType *next, *prev;
98         /** Only for debugging. */
99         const char *name;
100
101         /**
102          * When NULL, we don't consider this undo type for context checks.
103          * Operators must explicitly set the undo type and handle adding the undo step.
104          * This is needed when tools operate on data which isn't the primary mode (eg, paint-curve in sculpt mode).
105          */
106         bool (*poll)(struct bContext *C);
107
108         /**
109          * None of these callbacks manage list add/removal.
110          *
111          * Note that 'step_encode_init' is optional,
112          * some undo types need to perform operatons before undo push finishes.
113          */
114         void (*step_encode_init)(struct bContext *C, UndoStep *us);
115
116         bool (*step_encode)(struct bContext *C, UndoStep *us);
117         void (*step_decode)(struct bContext *C, UndoStep *us, int dir);
118
119         /**
120          * \note When freeing all steps,
121          * free from the last since #MemFileUndoType will merge with the next undo type in the list. */
122         void (*step_free)(UndoStep *us);
123
124         void (*step_foreach_ID_ref)(UndoStep *us, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data);
125
126         eUndoTypeMode mode;
127         bool use_context;
128
129         int step_size;
130 } UndoType;
131
132 /* expose since we need to perform operations on spesific undo types (rarely). */
133 extern const UndoType *BKE_UNDOSYS_TYPE_IMAGE;
134 extern const UndoType *BKE_UNDOSYS_TYPE_MEMFILE;
135 extern const UndoType *BKE_UNDOSYS_TYPE_PAINTCURVE;
136 extern const UndoType *BKE_UNDOSYS_TYPE_PARTICLE;
137 extern const UndoType *BKE_UNDOSYS_TYPE_SCULPT;
138 extern const UndoType *BKE_UNDOSYS_TYPE_TEXT;
139
140 UndoStack      *BKE_undosys_stack_create(void);
141 void            BKE_undosys_stack_destroy(UndoStack *ustack);
142 void            BKE_undosys_stack_clear(UndoStack *ustack);
143 void            BKE_undosys_stack_clear_active(UndoStack *ustack);
144 bool            BKE_undosys_stack_has_undo(UndoStack *ustack, const char *name);
145 void            BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain);
146 void            BKE_undosys_stack_init_from_context(UndoStack *ustack, struct bContext *C);
147 UndoStep       *BKE_undosys_stack_active_with_type(UndoStack *ustack, const UndoType *ut);
148 UndoStep       *BKE_undosys_stack_init_or_active_with_type(UndoStack *ustack, const UndoType *ut);
149 void            BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size_t memory_limit);
150
151 /* Only some UndoType's require init. */
152 UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, struct bContext *C, const char *name, const UndoType *ut);
153 UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, struct bContext *C, const char *name);
154
155 bool BKE_undosys_step_push_with_type(UndoStack *ustack, struct bContext *C, const char *name, const UndoType *ut);
156 bool BKE_undosys_step_push(UndoStack *ustack, struct bContext *C, const char *name);
157
158 UndoStep *BKE_undosys_step_find_by_name_with_type(UndoStack *ustack, const char *name, const UndoType *ut);
159 UndoStep *BKE_undosys_step_find_by_type(UndoStack *ustack, const UndoType *ut);
160 UndoStep *BKE_undosys_step_find_by_name(UndoStack *ustack, const char *name);
161
162 bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack, struct bContext *C, UndoStep *us, bool use_skip);
163 bool BKE_undosys_step_undo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
164 bool BKE_undosys_step_undo(UndoStack *ustack, struct bContext *C);
165
166 bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack, struct bContext *C, UndoStep *us, bool use_skip);
167 bool BKE_undosys_step_redo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
168 bool BKE_undosys_step_redo(UndoStack *ustack, struct bContext *C);
169
170 bool BKE_undosys_step_load_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
171
172 bool BKE_undosys_step_undo_compat_only(UndoStack *ustack, struct bContext *C, int step);
173 void BKE_undosys_step_undo_from_index(UndoStack *ustack, struct bContext *C, int index);
174 UndoStep *BKE_undosys_step_same_type_next(UndoStep *us);
175 UndoStep *BKE_undosys_step_same_type_prev(UndoStep *us);
176
177 /* Type System */
178 UndoType *BKE_undosys_type_append(void (*undosys_fn)(UndoType *));
179 void      BKE_undosys_type_free_all(void);
180
181 /* ID Accessor */
182 #if 0  /* functionality is only used internally for now. */
183 void BKE_undosys_foreach_ID_ref(UndoStack *ustack, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data);
184 #endif
185
186 /* Use when the undo step stores many arbitrary pointers. */
187 struct UndoIDPtrMap;
188 struct UndoIDPtrMap *BKE_undosys_ID_map_create(void);
189 void                 BKE_undosys_ID_map_destroy(struct UndoIDPtrMap *map);
190 void                 BKE_undosys_ID_map_add(struct UndoIDPtrMap *map, ID *id);
191 struct ID           *BKE_undosys_ID_map_lookup(const struct UndoIDPtrMap *map, const struct ID *id_src);
192
193 void BKE_undosys_ID_map_add_with_prev(
194         struct UndoIDPtrMap *map, struct ID *id,
195         struct ID **id_prev);
196 struct ID *BKE_undosys_ID_map_lookup_with_prev(
197         const struct UndoIDPtrMap *map, struct ID *id_src,
198         struct ID *id_prev_match[2]);
199
200 void BKE_undosys_ID_map_foreach_ID_ref(
201         struct UndoIDPtrMap *map,
202         UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data);
203
204 #endif  /* __BKE_UNDO_SYSTEM_H__ */