// #define RENDERER_CONFIG SDL_RENDERER_SOFTWARE
#define RENDERER_CONFIG (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)
+#define UNDO_HISTORY_CAPACITY 256
+
#endif // CONFIG_H_
level_editor->camera_scale = 1.0f;
+ level_editor->undo_history = create_undo_history();
+
return level_editor;
}
level_editor->camera_scale = 1.0f;
- log_info("%ld bytes of tmp memory consumed during parsing the level\n", tmpmem.size);
+ level_editor->undo_history = create_undo_history();
free(tmpmem.buffer);
#include "system/lt.h"
#include "system/stacktrace.h"
#include "undo_history.h"
+#include "config.h"
typedef struct {
RevertAction revert;
-} HistoryAction;
+ void *context_data;
+ size_t context_data_size;
+} HistoryItem;
+
+static
+void undo_history_destroy_item(void *item)
+{
+ free(((HistoryItem*)item)->context_data);
+}
+
+UndoHistory create_undo_history(void)
+{
+ UndoHistory result;
+ result.actions = create_ring_buffer(
+ sizeof(HistoryItem),
+ UNDO_HISTORY_CAPACITY,
+ undo_history_destroy_item);
+ return result;
+}
void undo_history_push(UndoHistory *undo_history,
RevertAction revert,
{
trace_assert(undo_history);
- HistoryAction action = {
+ HistoryItem item = {
.revert = revert,
+ .context_data = malloc(context_data_size),
+ .context_data_size = context_data_size
};
+ trace_assert(item.context_data);
+ memcpy(item.context_data, context_data, context_data_size);
- stack_push(&undo_history->actions, context_data, context_data_size);
- stack_push(&undo_history->actions, &action, sizeof(action));
+ ring_buffer_push(&undo_history->actions, &item);
}
void undo_history_pop(UndoHistory *undo_history)
{
trace_assert(undo_history);
- if (stack_empty(&undo_history->actions) > 0) {
- HistoryAction action = *(HistoryAction *)stack_top_element(&undo_history->actions);
- stack_pop(&undo_history->actions);
-
- size_t context_size = stack_top_size(&undo_history->actions);
- void *context = stack_top_element(&undo_history->actions);
-
- action.revert(context, context_size);
- stack_pop(&undo_history->actions);
+ 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);
}
}
#ifndef UNDO_HISTORY_H_
#define UNDO_HISTORY_H_
-#include "stack.h"
+#include "ring_buffer.h"
typedef void (*RevertAction)(void *context, size_t context_size);
typedef struct {
- Stack actions;
+ RingBuffer actions;
} UndoHistory;
+UndoHistory create_undo_history(void);
+
static inline
void destroy_undo_history(UndoHistory undo_history)
{
- destroy_stack(undo_history.actions);
+ destroy_ring_buffer(undo_history.actions);
}
void undo_history_push(UndoHistory *undo_history,
static inline
int undo_history_empty(UndoHistory *undo_history)
{
- return undo_history->actions.size == 0;
+ return undo_history->actions.count == 0;
}
#endif // UNDO_HISTORY_H_
+++ /dev/null
-#ifndef STACK_H_
-#define STACK_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <system/stacktrace.h>
-
-typedef struct {
- size_t capacity;
- size_t size;
- char *bottom;
-} Stack;
-
-static inline
-void destroy_stack(Stack stack)
-{
- free(stack.bottom);
-}
-
-static inline
-void stack_grow(Stack *stack, size_t new_capacity)
-{
- trace_assert(stack);
- trace_assert(stack->capacity < new_capacity);
-
- stack->bottom = realloc(stack->bottom, new_capacity);
- stack->capacity = new_capacity;
-}
-
-static inline
-void stack_push(Stack *stack, const void *element, size_t element_size)
-{
- trace_assert(stack);
- trace_assert(element);
- trace_assert(element_size > 0);
-
- size_t frame_size = element_size + sizeof(element_size);
-
- if (frame_size >= (stack->capacity - stack->size)) {
- stack_grow(stack, stack->capacity * 2 + frame_size);
- }
-
- trace_assert(stack->bottom);
-
- memcpy(stack->bottom + stack->size, element, element_size);
- stack->size += element_size;
- memcpy(stack->bottom + stack->size, &element_size, sizeof(element_size));
- stack->size += sizeof(element_size);
-}
-
-static inline
-size_t stack_top_size(const Stack *stack)
-{
- trace_assert(stack);
- trace_assert(stack->size > 0);
- trace_assert(stack->bottom);
- size_t stack_size = 0;
- memcpy(&stack_size, stack->bottom + stack->size - sizeof(size_t), sizeof(size_t));
- return stack_size;
-}
-
-static inline
-void *stack_top_element(const Stack *stack)
-{
- trace_assert(stack);
- trace_assert(stack->size > 0);
- trace_assert(stack->bottom);
- size_t element_size = stack_top_size(stack);
- return stack->bottom + stack->size - element_size - sizeof(size_t);
-}
-
-static inline
-void stack_pop(Stack *stack)
-{
- trace_assert(stack);
- trace_assert(stack->size > 0);
- size_t element_size = stack_top_size(stack);
- stack->size -= element_size + sizeof(size_t);
-}
-
-static inline
-int stack_empty(Stack *stack)
-{
- trace_assert(stack);
- return stack->size > 0;
-}
-
-#endif // STACK_H_