From 4c1a95e77c6d5c8b02e3256891c4c6afc56ed3e7 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 6 Jan 2020 01:32:59 +0700 Subject: [PATCH] Migrate UndoHistory's backend to RingBuffah --- src/config.h | 2 + src/game/level/level_editor.c | 4 +- src/game/level/level_editor/undo_history.c | 43 +++++++---- src/game/level/level_editor/undo_history.h | 10 ++- src/stack.h | 89 ---------------------- 5 files changed, 41 insertions(+), 107 deletions(-) delete mode 100644 src/stack.h diff --git a/src/config.h b/src/config.h index b062ebca..1431bb0b 100644 --- a/src/config.h +++ b/src/config.h @@ -31,4 +31,6 @@ // #define RENDERER_CONFIG SDL_RENDERER_SOFTWARE #define RENDERER_CONFIG (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC) +#define UNDO_HISTORY_CAPACITY 256 + #endif // CONFIG_H_ diff --git a/src/game/level/level_editor.c b/src/game/level/level_editor.c index 36f80f45..71011501 100644 --- a/src/game/level/level_editor.c +++ b/src/game/level/level_editor.c @@ -140,6 +140,8 @@ LevelEditor *create_level_editor(Cursor *cursor) level_editor->camera_scale = 1.0f; + level_editor->undo_history = create_undo_history(); + return level_editor; } @@ -228,7 +230,7 @@ LevelEditor *create_level_editor_from_file(const char *file_name, Cursor *cursor 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); diff --git a/src/game/level/level_editor/undo_history.c b/src/game/level/level_editor/undo_history.c index 7a51aaba..e5b6d428 100644 --- a/src/game/level/level_editor/undo_history.c +++ b/src/game/level/level_editor/undo_history.c @@ -7,10 +7,29 @@ #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, @@ -19,26 +38,24 @@ void undo_history_push(UndoHistory *undo_history, { 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); } } diff --git a/src/game/level/level_editor/undo_history.h b/src/game/level/level_editor/undo_history.h index bb671d12..e5af7ccb 100644 --- a/src/game/level/level_editor/undo_history.h +++ b/src/game/level/level_editor/undo_history.h @@ -1,18 +1,20 @@ #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, @@ -24,7 +26,7 @@ void undo_history_pop(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_ diff --git a/src/stack.h b/src/stack.h deleted file mode 100644 index 3ab4454b..00000000 --- a/src/stack.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef STACK_H_ -#define STACK_H_ - -#include -#include -#include -#include - -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_ -- 2.44.0