Line data Source code
1 : /* File: ctrl_undo_redo_list.inl; Copyright and License: see below */
2 :
3 : #include "u8/u8_trace.h"
4 : #include "u8/u8_log.h"
5 : #include <assert.h>
6 :
7 42 : static inline void ctrl_undo_redo_list_init ( ctrl_undo_redo_list_t *this_, data_database_reader_t *db_reader, data_database_writer_t *db_writer )
8 : {
9 42 : assert( NULL != db_reader );
10 42 : assert( NULL != db_writer );
11 :
12 42 : (*this_).db_reader = db_reader;
13 42 : (*this_).db_writer = db_writer;
14 :
15 42 : ctrl_undo_redo_entry_init( &((*this_).buffer[0]), CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY );
16 42 : (*this_).start = 0;
17 42 : (*this_).length = 1;
18 42 : (*this_).current = 1;
19 42 : (*this_).buffer_incomplete = false;
20 42 : }
21 :
22 42 : static inline void ctrl_undo_redo_list_destroy ( ctrl_undo_redo_list_t *this_ )
23 : {
24 42 : ctrl_undo_redo_list_clear( this_ );
25 42 : (*this_).db_reader = NULL;
26 42 : (*this_).db_writer = NULL;
27 42 : }
28 :
29 48 : static inline void ctrl_undo_redo_list_clear ( ctrl_undo_redo_list_t *this_ )
30 : {
31 48 : assert( (*this_).start < CTRL_UNDO_REDO_LIST_MAX_SIZE );
32 48 : assert( (*this_).length <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
33 48 : assert( (*this_).current <= (*this_).length );
34 :
35 : /* call destructors of elements: */
36 421 : for ( uint32_t pos = 0; pos < (*this_).length; pos ++ )
37 : {
38 373 : uint32_t index = ((*this_).start + pos) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
39 373 : ctrl_undo_redo_entry_destroy( &((*this_).buffer[index]) );
40 : }
41 :
42 : /* reset: */
43 48 : ctrl_undo_redo_entry_init( &((*this_).buffer[0]), CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY );
44 48 : (*this_).start = 0;
45 48 : (*this_).length = 1;
46 48 : (*this_).current = 1;
47 48 : (*this_).buffer_incomplete = false;
48 48 : }
49 :
50 341 : static inline u8_error_t ctrl_undo_redo_list_add_boundary ( ctrl_undo_redo_list_t *this_ )
51 : {
52 341 : u8_error_t result = U8_ERROR_NONE;
53 : ctrl_undo_redo_entry_t *list_entry;
54 :
55 : /* add and re-initialize the list entry */
56 341 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
57 341 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY );
58 :
59 : /* check if >=1 complete set of transactions is still in the undo-redo-list */
60 341 : if ( 1 == ctrl_undo_redo_list_private_count_boundaries( this_, (*this_).start, (*this_).length ) )
61 : {
62 0 : result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
63 : }
64 :
65 341 : return result;
66 : }
67 :
68 : /* ================================ DIAGRAM ================================ */
69 :
70 2 : static inline void ctrl_undo_redo_list_add_delete_diagram ( ctrl_undo_redo_list_t *this_, data_diagram_t *old_value )
71 : {
72 : ctrl_undo_redo_entry_t *list_entry;
73 : data_diagram_t *list_entry_old;
74 : data_diagram_t *list_entry_new;
75 :
76 : /* add and re-initialize the list entry */
77 2 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
78 2 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAM );
79 :
80 : /* copy the values */
81 2 : list_entry_old = ctrl_undo_redo_entry_get_diagram_before_action_ptr( list_entry );
82 2 : data_diagram_replace( list_entry_old, old_value );
83 2 : list_entry_new = ctrl_undo_redo_entry_get_diagram_after_action_ptr( list_entry );
84 2 : data_diagram_init_empty( list_entry_new );
85 2 : }
86 :
87 9 : static inline void ctrl_undo_redo_list_add_update_diagram ( ctrl_undo_redo_list_t *this_, data_diagram_t *old_value, data_diagram_t *new_value )
88 : {
89 : ctrl_undo_redo_entry_t *list_entry;
90 : data_diagram_t *list_entry_old;
91 : data_diagram_t *list_entry_new;
92 :
93 : /* add and re-initialize the list entry */
94 9 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
95 9 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAM );
96 :
97 : /* copy the values */
98 9 : list_entry_old = ctrl_undo_redo_entry_get_diagram_before_action_ptr( list_entry );
99 9 : data_diagram_replace( list_entry_old, old_value );
100 9 : list_entry_new = ctrl_undo_redo_entry_get_diagram_after_action_ptr( list_entry );
101 9 : data_diagram_replace( list_entry_new, new_value );
102 9 : }
103 :
104 162 : static inline void ctrl_undo_redo_list_add_create_diagram ( ctrl_undo_redo_list_t *this_, data_diagram_t *new_value )
105 : {
106 : ctrl_undo_redo_entry_t *list_entry;
107 : data_diagram_t *list_entry_old;
108 : data_diagram_t *list_entry_new;
109 :
110 : /* add and re-initialize the list entry */
111 162 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
112 162 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAM );
113 :
114 : /* copy the values */
115 162 : list_entry_old = ctrl_undo_redo_entry_get_diagram_before_action_ptr( list_entry );
116 162 : data_diagram_init_empty( list_entry_old );
117 162 : list_entry_new = ctrl_undo_redo_entry_get_diagram_after_action_ptr( list_entry );
118 162 : data_diagram_replace( list_entry_new, new_value );
119 162 : }
120 :
121 : /* ================================ DIAGRAMELEMENT ================================ */
122 :
123 5 : static inline void ctrl_undo_redo_list_add_delete_diagramelement ( ctrl_undo_redo_list_t *this_, data_diagramelement_t *old_value )
124 : {
125 : ctrl_undo_redo_entry_t *list_entry;
126 : data_diagramelement_t *list_entry_old;
127 : data_diagramelement_t *list_entry_new;
128 :
129 : /* add and re-initialize the list entry */
130 5 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
131 5 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAMELEMENT );
132 :
133 : /* copy the values */
134 5 : list_entry_old = ctrl_undo_redo_entry_get_diagramelement_before_action_ptr( list_entry );
135 5 : data_diagramelement_replace( list_entry_old, old_value );
136 5 : list_entry_new = ctrl_undo_redo_entry_get_diagramelement_after_action_ptr( list_entry );
137 5 : data_diagramelement_init_empty( list_entry_new );
138 5 : }
139 :
140 22 : static inline void ctrl_undo_redo_list_add_update_diagramelement ( ctrl_undo_redo_list_t *this_, data_diagramelement_t *old_value, data_diagramelement_t *new_value )
141 : {
142 : ctrl_undo_redo_entry_t *list_entry;
143 : data_diagramelement_t *list_entry_old;
144 : data_diagramelement_t *list_entry_new;
145 :
146 : /* add and re-initialize the list entry */
147 22 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
148 22 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAMELEMENT );
149 :
150 : /* copy the values */
151 22 : list_entry_old = ctrl_undo_redo_entry_get_diagramelement_before_action_ptr( list_entry );
152 22 : data_diagramelement_replace( list_entry_old, old_value );
153 22 : list_entry_new = ctrl_undo_redo_entry_get_diagramelement_after_action_ptr( list_entry );
154 22 : data_diagramelement_replace( list_entry_new, new_value );
155 22 : }
156 :
157 33 : static inline void ctrl_undo_redo_list_add_create_diagramelement ( ctrl_undo_redo_list_t *this_, data_diagramelement_t *new_value )
158 : {
159 : ctrl_undo_redo_entry_t *list_entry;
160 : data_diagramelement_t *list_entry_old;
161 : data_diagramelement_t *list_entry_new;
162 :
163 : /* add and re-initialize the list entry */
164 33 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
165 33 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAMELEMENT );
166 :
167 : /* copy the values */
168 33 : list_entry_old = ctrl_undo_redo_entry_get_diagramelement_before_action_ptr( list_entry );
169 33 : data_diagramelement_init_empty( list_entry_old );
170 33 : list_entry_new = ctrl_undo_redo_entry_get_diagramelement_after_action_ptr( list_entry );
171 33 : data_diagramelement_replace( list_entry_new, new_value );
172 33 : }
173 :
174 : /* ================================ CLASSIFIER ================================ */
175 :
176 3 : static inline void ctrl_undo_redo_list_add_delete_classifier ( ctrl_undo_redo_list_t *this_, data_classifier_t *old_value )
177 : {
178 : ctrl_undo_redo_entry_t *list_entry;
179 : data_classifier_t *list_entry_old;
180 : data_classifier_t *list_entry_new;
181 :
182 : /* add and re-initialize the list entry */
183 3 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
184 3 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_CLASSIFIER );
185 :
186 : /* copy the values */
187 3 : list_entry_old = ctrl_undo_redo_entry_get_classifier_before_action_ptr( list_entry );
188 3 : data_classifier_replace( list_entry_old, old_value );
189 3 : list_entry_new = ctrl_undo_redo_entry_get_classifier_after_action_ptr( list_entry );
190 3 : data_classifier_init_empty( list_entry_new );
191 3 : }
192 :
193 7 : static inline void ctrl_undo_redo_list_add_update_classifier ( ctrl_undo_redo_list_t *this_, data_classifier_t *old_value, data_classifier_t *new_value )
194 : {
195 : ctrl_undo_redo_entry_t *list_entry;
196 : data_classifier_t *list_entry_old;
197 : data_classifier_t *list_entry_new;
198 :
199 : /* add and re-initialize the list entry */
200 7 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
201 7 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_CLASSIFIER );
202 :
203 : /* copy the values */
204 7 : list_entry_old = ctrl_undo_redo_entry_get_classifier_before_action_ptr( list_entry );
205 7 : data_classifier_replace( list_entry_old, old_value );
206 7 : list_entry_new = ctrl_undo_redo_entry_get_classifier_after_action_ptr( list_entry );
207 7 : data_classifier_replace( list_entry_new, new_value );
208 7 : }
209 :
210 26 : static inline void ctrl_undo_redo_list_add_create_classifier ( ctrl_undo_redo_list_t *this_, data_classifier_t *new_value )
211 : {
212 : ctrl_undo_redo_entry_t *list_entry;
213 : data_classifier_t *list_entry_old;
214 : data_classifier_t *list_entry_new;
215 :
216 : /* add and re-initialize the list entry */
217 26 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
218 26 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_CLASSIFIER );
219 :
220 : /* copy the values */
221 26 : list_entry_old = ctrl_undo_redo_entry_get_classifier_before_action_ptr( list_entry );
222 26 : data_classifier_init_empty( list_entry_old );
223 26 : list_entry_new = ctrl_undo_redo_entry_get_classifier_after_action_ptr( list_entry );
224 26 : data_classifier_replace( list_entry_new, new_value );
225 26 : }
226 :
227 : /* ================================ FEATURE ================================ */
228 :
229 9 : static inline void ctrl_undo_redo_list_add_delete_feature ( ctrl_undo_redo_list_t *this_, data_feature_t *old_value )
230 : {
231 : ctrl_undo_redo_entry_t *list_entry;
232 : data_feature_t *list_entry_old;
233 : data_feature_t *list_entry_new;
234 :
235 : /* add and re-initialize the list entry */
236 9 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
237 9 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_FEATURE );
238 :
239 : /* copy the values */
240 9 : list_entry_old = ctrl_undo_redo_entry_get_feature_before_action_ptr( list_entry );
241 9 : data_feature_replace( list_entry_old, old_value );
242 9 : list_entry_new = ctrl_undo_redo_entry_get_feature_after_action_ptr( list_entry );
243 9 : data_feature_init_empty( list_entry_new );
244 9 : }
245 :
246 7 : static inline void ctrl_undo_redo_list_add_update_feature ( ctrl_undo_redo_list_t *this_, data_feature_t *old_value, data_feature_t *new_value )
247 : {
248 : ctrl_undo_redo_entry_t *list_entry;
249 : data_feature_t *list_entry_old;
250 : data_feature_t *list_entry_new;
251 :
252 : /* add and re-initialize the list entry */
253 7 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
254 7 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_FEATURE );
255 :
256 : /* copy the values */
257 7 : list_entry_old = ctrl_undo_redo_entry_get_feature_before_action_ptr( list_entry );
258 7 : data_feature_replace( list_entry_old, old_value );
259 7 : list_entry_new = ctrl_undo_redo_entry_get_feature_after_action_ptr( list_entry );
260 7 : data_feature_replace( list_entry_new, new_value );
261 7 : }
262 :
263 32 : static inline void ctrl_undo_redo_list_add_create_feature ( ctrl_undo_redo_list_t *this_, data_feature_t *new_value )
264 : {
265 : ctrl_undo_redo_entry_t *list_entry;
266 : data_feature_t *list_entry_old;
267 : data_feature_t *list_entry_new;
268 :
269 : /* add and re-initialize the list entry */
270 32 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
271 32 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_FEATURE );
272 :
273 : /* copy the values */
274 32 : list_entry_old = ctrl_undo_redo_entry_get_feature_before_action_ptr( list_entry );
275 32 : data_feature_init_empty( list_entry_old );
276 32 : list_entry_new = ctrl_undo_redo_entry_get_feature_after_action_ptr( list_entry );
277 32 : data_feature_replace( list_entry_new, new_value );
278 32 : }
279 :
280 : /* ================================ RELATIONSHIP ================================ */
281 :
282 5 : static inline void ctrl_undo_redo_list_add_delete_relationship ( ctrl_undo_redo_list_t *this_, data_relationship_t *old_value )
283 : {
284 : ctrl_undo_redo_entry_t *list_entry;
285 : data_relationship_t *list_entry_old;
286 : data_relationship_t *list_entry_new;
287 :
288 : /* add and re-initialize the list entry */
289 5 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
290 5 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_RELATIONSHIP );
291 :
292 : /* copy the values */
293 5 : list_entry_old = ctrl_undo_redo_entry_get_relationship_before_action_ptr( list_entry );
294 5 : data_relationship_replace( list_entry_old, old_value );
295 5 : list_entry_new = ctrl_undo_redo_entry_get_relationship_after_action_ptr( list_entry );
296 5 : data_relationship_init_empty( list_entry_new );
297 5 : }
298 :
299 6 : static inline void ctrl_undo_redo_list_add_update_relationship ( ctrl_undo_redo_list_t *this_, data_relationship_t *old_value, data_relationship_t *new_value )
300 : {
301 : ctrl_undo_redo_entry_t *list_entry;
302 : data_relationship_t *list_entry_old;
303 : data_relationship_t *list_entry_new;
304 :
305 : /* add and re-initialize the list entry */
306 6 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
307 6 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_RELATIONSHIP );
308 :
309 : /* copy the values */
310 6 : list_entry_old = ctrl_undo_redo_entry_get_relationship_before_action_ptr( list_entry );
311 6 : data_relationship_replace( list_entry_old, old_value );
312 6 : list_entry_new = ctrl_undo_redo_entry_get_relationship_after_action_ptr( list_entry );
313 6 : data_relationship_replace( list_entry_new, new_value );
314 6 : }
315 :
316 13 : static inline void ctrl_undo_redo_list_add_create_relationship ( ctrl_undo_redo_list_t *this_, data_relationship_t *new_value )
317 : {
318 : ctrl_undo_redo_entry_t *list_entry;
319 : data_relationship_t *list_entry_old;
320 : data_relationship_t *list_entry_new;
321 :
322 : /* add and re-initialize the list entry */
323 13 : list_entry = ctrl_undo_redo_list_private_add_entry_ptr( this_ );
324 13 : ctrl_undo_redo_entry_reinit( list_entry, CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_RELATIONSHIP );
325 :
326 : /* copy the values */
327 13 : list_entry_old = ctrl_undo_redo_entry_get_relationship_before_action_ptr( list_entry );
328 13 : data_relationship_init_empty( list_entry_old );
329 13 : list_entry_new = ctrl_undo_redo_entry_get_relationship_after_action_ptr( list_entry );
330 13 : data_relationship_replace( list_entry_new, new_value );
331 13 : }
332 :
333 : /* ================================ private ================================ */
334 :
335 487 : static inline uint32_t ctrl_undo_redo_list_private_count_boundaries ( ctrl_undo_redo_list_t *this_, uint32_t start_idx, uint32_t search_len )
336 : {
337 487 : assert( search_len <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
338 :
339 487 : uint32_t result = 0;
340 36186 : for ( uint32_t pos = 0; pos < search_len; pos ++ )
341 : {
342 35699 : uint32_t index = (start_idx + pos) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
343 35699 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY == ctrl_undo_redo_entry_get_action_type( &((*this_).buffer[index]) ) )
344 : {
345 17707 : result ++;
346 : }
347 : }
348 487 : return result;
349 : }
350 :
351 :
352 : /*
353 : Copyright 2016-2024 Andreas Warnke
354 :
355 : Licensed under the Apache License, Version 2.0 (the "License");
356 : you may not use this file except in compliance with the License.
357 : You may obtain a copy of the License at
358 :
359 : http://www.apache.org/licenses/LICENSE-2.0
360 :
361 : Unless required by applicable law or agreed to in writing, software
362 : distributed under the License is distributed on an "AS IS" BASIS,
363 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
364 : See the License for the specific language governing permissions and
365 : limitations under the License.
366 : */
|