]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/level_editor/undo_history.c
Try to remove malloc from LevelEditor
[nothing.git] / src / game / level / level_editor / undo_history.c
index d69619e3f153ec2b7e2f192d7c93d880795845c6..f1e933ffd5bc6b267b99484ee770a05851444c61 100644 (file)
@@ -1,56 +1,63 @@
 #include <stdlib.h>
+#include <stdio.h>
 
 #include <SDL.h>
 
 #include "system/nth_alloc.h"
-#include "system/lt.h"
-#include "dynarray.h"
 #include "system/stacktrace.h"
 #include "undo_history.h"
+#include "config.h"
 
-struct UndoHistory
-{
-    Lt *lt;
-    Dynarray *actions;
-};
+typedef struct {
+    RevertAction revert;
+    void *context_data;
+    size_t context_data_size;
+} HistoryItem;
 
-UndoHistory *create_undo_history(void)
+UndoHistory *create_undo_history_from_memory(Memory *memory)
 {
-    Lt *lt = create_lt();
-
-    UndoHistory *undo_history = PUSH_LT(
-        lt,
-        nth_calloc(1, sizeof(UndoHistory)),
-        free);
-    undo_history->lt = lt;
-
-    undo_history->actions = PUSH_LT(
-        lt,
-        create_dynarray(sizeof(Action)),
-        destroy_dynarray);
-
-    return undo_history;
+    UndoHistory *result = memory_alloc(memory, sizeof(UndoHistory));
+    result->actions = create_ring_buffer_from_buffer(
+        memory,
+        sizeof(HistoryItem),
+        UNDO_HISTORY_CAPACITY);
+    result->memory = memory;
+    return result;
 }
 
-void destroy_undo_history(UndoHistory *undo_history)
+void undo_history_push(UndoHistory *undo_history,
+                       RevertAction revert,
+                       void *context_data,
+                       size_t context_data_size)
 {
     trace_assert(undo_history);
-    RETURN_LT0(undo_history->lt);
+
+    // TODO: undo_history_push kinda leaks the memory
+    HistoryItem item = {
+        .revert = revert,
+        .context_data = memory_alloc(undo_history->memory, context_data_size),
+        .context_data_size = context_data_size
+    };
+    memcpy(item.context_data, context_data, context_data_size);
+    ring_buffer_push(&undo_history->actions, &item);
 }
 
-void undo_history_push(UndoHistory *undo_history, Action action)
+void undo_history_pop(UndoHistory *undo_history)
 {
     trace_assert(undo_history);
-    dynarray_push(undo_history->actions, &action);
+
+    if (undo_history->actions.count > 0) {
+        HistoryItem *item = ring_buffer_top(&undo_history->actions);
+        item->revert(item->context_data, item->context_data_size);
+        ring_buffer_pop(&undo_history->actions);
+    }
 }
 
-void undo_history_pop(UndoHistory *undo_history)
+void undo_history_clean(UndoHistory *undo_history)
 {
     trace_assert(undo_history);
 
-    if (dynarray_count(undo_history->actions) > 0) {
-        Action action;
-        dynarray_pop(undo_history->actions, &action);
-        action.revert(action.layer, action.context);
+    while (undo_history->actions.count) {
+        ring_buffer_pop(&undo_history->actions);
     }
 }