]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/undo_history.c
Migrate UndoHistory's backend to RingBuffah
[nothing.git] / src / game / level / level_editor / undo_history.c
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include <SDL.h>
5
6 #include "system/nth_alloc.h"
7 #include "system/lt.h"
8 #include "system/stacktrace.h"
9 #include "undo_history.h"
10 #include "config.h"
11
12 typedef struct {
13     RevertAction revert;
14     void *context_data;
15     size_t context_data_size;
16 } HistoryItem;
17
18 static
19 void undo_history_destroy_item(void *item)
20 {
21     free(((HistoryItem*)item)->context_data);
22 }
23
24 UndoHistory create_undo_history(void)
25 {
26     UndoHistory result;
27     result.actions = create_ring_buffer(
28         sizeof(HistoryItem),
29         UNDO_HISTORY_CAPACITY,
30         undo_history_destroy_item);
31     return result;
32 }
33
34 void undo_history_push(UndoHistory *undo_history,
35                        RevertAction revert,
36                        void *context_data,
37                        size_t context_data_size)
38 {
39     trace_assert(undo_history);
40
41     HistoryItem item = {
42         .revert = revert,
43         .context_data = malloc(context_data_size),
44         .context_data_size = context_data_size
45     };
46     trace_assert(item.context_data);
47     memcpy(item.context_data, context_data, context_data_size);
48
49     ring_buffer_push(&undo_history->actions, &item);
50 }
51
52 void undo_history_pop(UndoHistory *undo_history)
53 {
54     trace_assert(undo_history);
55
56     if (undo_history->actions.count > 0) {
57         HistoryItem *item = ring_buffer_top(&undo_history->actions);
58         item->revert(item->context_data, item->context_data_size);
59         ring_buffer_pop(&undo_history->actions);
60     }
61 }