From c1021a9d6a49eae97ad17755414279530ca9e21c Mon Sep 17 00:00:00 2001 From: rexim Date: Sun, 12 Jan 2020 01:58:06 +0700 Subject: [PATCH] Try to remove malloc from LevelEditor --- src/config.h | 2 + src/dynarray.h | 12 ++ src/game.c | 56 +++++---- src/game/level.c | 14 +-- src/game/level/level_editor.c | 126 ++++++++------------- src/game/level/level_editor.h | 25 ++-- src/game/level/level_editor/label_layer.c | 33 ++++-- src/game/level/level_editor/label_layer.h | 4 +- src/game/level/level_editor/point_layer.c | 34 +++--- src/game/level/level_editor/point_layer.h | 5 +- src/game/level/level_editor/rect_layer.c | 43 +++---- src/game/level/level_editor/rect_layer.h | 9 +- src/game/level/level_editor/undo_history.c | 22 ++-- src/game/level/level_editor/undo_history.h | 9 +- src/ring_buffer.c | 7 -- src/ring_buffer.h | 16 +-- src/system/memory.h | 1 - src/system/s.h | 12 ++ 18 files changed, 213 insertions(+), 217 deletions(-) diff --git a/src/config.h b/src/config.h index f26ea0d2..6be65940 100644 --- a/src/config.h +++ b/src/config.h @@ -37,4 +37,6 @@ #define TMPMEM_CAPACITY (640 * KILO) +#define LEVEL_EDITOR_MEMORY_CAPACITY (640 * KILO) + #endif // CONFIG_H_ diff --git a/src/dynarray.h b/src/dynarray.h index 39bc1b91..15f228f2 100644 --- a/src/dynarray.h +++ b/src/dynarray.h @@ -24,6 +24,18 @@ Dynarray create_dynarray(size_t element_size) return result; } +static inline +Dynarray create_dynarray_from_memory(Memory *memory, size_t element_size) +{ + trace_assert(memory); + Dynarray result = { + .element_size = element_size, + .count = 0, + .data = memory_alloc(memory, DYNARRAY_CAPACITY * element_size) + }; + return result; +} + void *dynarray_pointer_at(const Dynarray *dynarray, size_t index); void dynarray_replace_at(Dynarray *dynarray, size_t index, void *element); void dynarray_copy_to(Dynarray *dynarray, void *dest, size_t index); diff --git a/src/game.c b/src/game.c index d0095283..c8615c72 100644 --- a/src/game.c +++ b/src/game.c @@ -24,9 +24,9 @@ typedef struct Game { Game_state state; Sprite_font font; - Memory tmpmem; + Memory level_editor_memory; LevelPicker level_picker; - LevelEditor level_editor; + LevelEditor *level_editor; Credits credits; Level *level; Settings settings; @@ -67,9 +67,9 @@ Game *create_game(const char *level_folder, renderer, "./assets/images/charmap-oldschool.bmp"); - game->tmpmem.capacity = TMPMEM_CAPACITY; - game->tmpmem.buffer = malloc(TMPMEM_CAPACITY); - trace_assert(game->tmpmem.buffer); + game->level_editor_memory.capacity = LEVEL_EDITOR_MEMORY_CAPACITY; + game->level_editor_memory.buffer = malloc(LEVEL_EDITOR_MEMORY_CAPACITY); + trace_assert(game->level_editor_memory.buffer); level_picker_populate(&game->level_picker, level_folder); @@ -109,7 +109,9 @@ Game *create_game(const char *level_folder, } } - create_level_editor(&game->level_editor, &game->cursor); + game->level_editor = create_level_editor_from_memory( + &game->level_editor_memory, + &game->cursor); game->console = PUSH_LT( lt, @@ -129,7 +131,7 @@ void destroy_game(Game *game) { trace_assert(game); destroy_level_picker(game->level_picker); - free(game->tmpmem.buffer); + free(game->level_editor_memory.buffer); RETURN_LT0(game->lt); } @@ -151,7 +153,7 @@ int game_render(const Game *game) } break; case GAME_STATE_LEVEL_EDITOR: { - if (level_editor_render(&game->level_editor, &game->camera) < 0) { + if (level_editor_render(game->level_editor, &game->camera) < 0) { return -1; } } break; @@ -188,7 +190,7 @@ int game_sound(Game *game) case GAME_STATE_LEVEL: return level_sound(game->level, game->sound_samples); case GAME_STATE_LEVEL_EDITOR: - level_editor_sound(&game->level_editor, game->sound_samples); + level_editor_sound(game->level_editor, game->sound_samples); return 0; case GAME_STATE_LEVEL_PICKER: case GAME_STATE_CREDITS: @@ -248,12 +250,12 @@ int game_update(Game *game, float delta_time) case GAME_STATE_LEVEL_EDITOR: { if (level_editor_focus_camera( - &game->level_editor, + game->level_editor, &game->camera) < 0) { return -1; } - level_editor_update(&game->level_editor, delta_time); + level_editor_update(game->level_editor, delta_time); } break; case GAME_STATE_CREDITS: { @@ -290,7 +292,7 @@ static int game_event_running(Game *game, const SDL_Event *event) game->lt, game->level, create_level_from_level_editor( - &game->level_editor)); + game->level_editor)); if (game->level == NULL) { game_switch_state(game, GAME_STATE_QUIT); return -1; @@ -323,20 +325,23 @@ static int game_event_level_picker(Game *game, const SDL_Event *event) case SDL_KEYDOWN: { switch(event->key.keysym.sym) { case SDLK_n: { - level_editor_clean(&game->level_editor); + memory_clean(&game->level_editor_memory); + game->level_editor = create_level_editor_from_memory( + &game->level_editor_memory, + &game->cursor); if (game->level == NULL) { game->level = PUSH_LT( game->lt, create_level_from_level_editor( - &game->level_editor), + game->level_editor), destroy_level); } else { game->level = RESET_LT( game->lt, game->level, create_level_from_level_editor( - &game->level_editor)); + game->level_editor)); } if (game->level == NULL) { @@ -373,7 +378,7 @@ static int game_event_level_editor(Game *game, const SDL_Event *event) game->lt, game->level, create_level_from_level_editor( - &game->level_editor)); + game->level_editor)); if (game->level == NULL) { return -1; } @@ -383,7 +388,7 @@ static int game_event_level_editor(Game *game, const SDL_Event *event) } break; } - return level_editor_event(&game->level_editor, event, &game->camera); + return level_editor_event(game->level_editor, event, &game->camera, &game->level_editor_memory); } int game_event(Game *game, const SDL_Event *event) @@ -526,21 +531,30 @@ int game_load_level(Game *game, const char *level_filename) trace_assert(game); trace_assert(level_filename); - memory_clean(&game->tmpmem); - level_editor_load_from_file(&game->level_editor, &game->tmpmem, level_filename); + memory_clean(&game->level_editor_memory); + game->level_editor = + create_level_editor_from_file_with_memory( + &game->level_editor_memory, + &game->cursor, + level_filename); + + if (!game->level_editor) { + game_switch_state(game, GAME_STATE_LEVEL_PICKER); + return 0; + } if (game->level == NULL) { game->level = PUSH_LT( game->lt, create_level_from_level_editor( - &game->level_editor), + game->level_editor), destroy_level); } else { game->level = RESET_LT( game->lt, game->level, create_level_from_level_editor( - &game->level_editor)); + game->level_editor)); } if (game->level == NULL) { diff --git a/src/game/level.c b/src/game/level.c index a65d6219..eeb5b654 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -86,7 +86,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->platforms = PUSH_LT( lt, - create_platforms_from_rect_layer(&level_editor->platforms_layer), + create_platforms_from_rect_layer(level_editor->platforms_layer), destroy_platforms); if (level->platforms == NULL) { RETURN_LT(lt, NULL); @@ -94,7 +94,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->goals = PUSH_LT( lt, - create_goals_from_point_layer(&level_editor->goals_layer), + create_goals_from_point_layer(level_editor->goals_layer), destroy_goals); if (level->goals == NULL) { RETURN_LT(lt, NULL); @@ -102,7 +102,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->lava = PUSH_LT( lt, - create_lava_from_rect_layer(&level_editor->lava_layer), + create_lava_from_rect_layer(level_editor->lava_layer), destroy_lava); if (level->lava == NULL) { RETURN_LT(lt, NULL); @@ -110,7 +110,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->back_platforms = PUSH_LT( lt, - create_platforms_from_rect_layer(&level_editor->back_platforms_layer), + create_platforms_from_rect_layer(level_editor->back_platforms_layer), destroy_platforms); if (level->back_platforms == NULL) { RETURN_LT(lt, NULL); @@ -118,7 +118,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->boxes = PUSH_LT( lt, - create_boxes_from_rect_layer(&level_editor->boxes_layer, level->rigid_bodies), + create_boxes_from_rect_layer(level_editor->boxes_layer, level->rigid_bodies), destroy_boxes); if (level->boxes == NULL) { RETURN_LT(lt, NULL); @@ -126,7 +126,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->labels = PUSH_LT( lt, - create_labels_from_label_layer(&level_editor->label_layer), + create_labels_from_label_layer(level_editor->label_layer), destroy_labels); if (level->labels == NULL) { RETURN_LT(lt, NULL); @@ -135,7 +135,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor) level->regions = PUSH_LT( lt, create_regions_from_rect_layer( - &level_editor->regions_layer, + level_editor->regions_layer, level->labels, level->goals), destroy_regions); diff --git a/src/game/level/level_editor.c b/src/game/level/level_editor.c index 0a434cae..f69d6adc 100644 --- a/src/game/level/level_editor.c +++ b/src/game/level/level_editor.c @@ -32,8 +32,9 @@ static int level_editor_dump(LevelEditor *level_editor); // TODO(#994): too much duplicate code between create_level_editor and create_level_editor_from_file -void create_level_editor(LevelEditor *level_editor, Cursor *cursor) +LevelEditor *create_level_editor_from_memory(Memory *memory, Cursor *cursor) { + LevelEditor *level_editor = memory_alloc(memory, sizeof(LevelEditor)); memset(level_editor, 0, sizeof(*level_editor)); level_editor->edit_field_filename.font_size = LEVEL_EDITOR_EDIT_FIELD_SIZE; @@ -41,23 +42,25 @@ void create_level_editor(LevelEditor *level_editor, Cursor *cursor) level_editor->background_layer = create_background_layer(hexstr("fffda5")); level_editor->player_layer = create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080")); - level_editor->platforms_layer = create_rect_layer("platform", cursor); - level_editor->goals_layer = create_point_layer("goal"), - level_editor->lava_layer = create_rect_layer("lava", cursor); - level_editor->back_platforms_layer = create_rect_layer("back_platform", cursor); - level_editor->boxes_layer = create_rect_layer("box", cursor); - level_editor->label_layer = create_label_layer("label"); - level_editor->regions_layer = create_rect_layer("region", cursor), - - level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(&level_editor->boxes_layer); - level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(&level_editor->platforms_layer); - level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(&level_editor->back_platforms_layer); - level_editor->layers[LAYER_PICKER_GOALS] = point_layer_as_layer(&level_editor->goals_layer); + + level_editor->platforms_layer = create_rect_layer_from_memory(memory, "platform", cursor); + level_editor->lava_layer = create_rect_layer_from_memory(memory, "lava", cursor); + level_editor->back_platforms_layer = create_rect_layer_from_memory(memory, "back_platform", cursor); + level_editor->boxes_layer = create_rect_layer_from_memory(memory, "box", cursor); + level_editor->regions_layer = create_rect_layer_from_memory(memory, "region", cursor); + level_editor->goals_layer = create_point_layer_from_memory(memory, "goal"); + level_editor->label_layer = create_label_layer_from_memory(memory, "label"); + + level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(level_editor->boxes_layer); + level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(level_editor->platforms_layer); + level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(level_editor->back_platforms_layer); + level_editor->layers[LAYER_PICKER_GOALS] = point_layer_as_layer(level_editor->goals_layer); level_editor->layers[LAYER_PICKER_PLAYER] = player_layer_as_layer(&level_editor->player_layer); - level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(&level_editor->lava_layer); - level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(&level_editor->regions_layer); + level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(level_editor->lava_layer); + level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(level_editor->regions_layer); level_editor->layers[LAYER_PICKER_BACKGROUND] = background_layer_as_layer(&level_editor->background_layer); - level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(&level_editor->label_layer); + level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(level_editor->label_layer); + level_editor->notice = (FadingWigglyText) { .wiggly_text = { @@ -69,17 +72,21 @@ void create_level_editor(LevelEditor *level_editor, Cursor *cursor) }; level_editor->camera_scale = 1.0f; - level_editor->undo_history = create_undo_history(); + level_editor->undo_history = create_undo_history_from_memory(memory); + + return level_editor; } -void level_editor_load_from_file(LevelEditor *level_editor, Memory *tmpmem, const char *file_name) +LevelEditor *create_level_editor_from_file_with_memory(Memory *memory, Cursor *cursor, const char *file_name) { + trace_assert(memory); + trace_assert(cursor); trace_assert(file_name); - if (level_editor->file_name) free(level_editor->file_name); - level_editor->file_name = string_duplicate(file_name, NULL); + LevelEditor *level_editor = create_level_editor_from_memory(memory, cursor); + level_editor->file_name = strdup_to_memory(memory, file_name); - String input = read_whole_file(tmpmem, file_name); + String input = read_whole_file(memory, file_name); trace_assert(input.data); String version = trim(chop_by_delim(&input, '\n')); @@ -90,58 +97,23 @@ void level_editor_load_from_file(LevelEditor *level_editor, Memory *tmpmem, cons // Nothing } else { log_fail("Version `%s` is not supported. Expected version `%s`.\n", - string_to_cstr(tmpmem, version), + string_to_cstr(memory, version), VERSION); - return; + return NULL; } level_editor->background_layer = chop_background_layer(&input); - level_editor->player_layer = chop_player_layer(tmpmem, &input); - rect_layer_reload(&level_editor->platforms_layer, tmpmem, &input); - point_layer_reload(&level_editor->goals_layer, tmpmem, &input); - rect_layer_reload(&level_editor->lava_layer, tmpmem, &input); - rect_layer_reload(&level_editor->back_platforms_layer, tmpmem, &input); - rect_layer_reload(&level_editor->boxes_layer, tmpmem, &input); - label_layer_reload(&level_editor->label_layer, tmpmem, &input); - rect_layer_reload(&level_editor->regions_layer, tmpmem, &input); - undo_history_clean(&level_editor->undo_history); -} - -void level_editor_clean(LevelEditor *level_editor) -{ - level_editor->camera_scale = 1.0f; - level_editor->camera_position = vec(0.0f, 0.0f); - if (level_editor->file_name) { - free(level_editor->file_name); - level_editor->file_name = NULL; - } - level_editor->background_layer = create_background_layer(hexstr("fffda5")); - level_editor->player_layer = create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080")); - rect_layer_clean(&level_editor->platforms_layer); - point_layer_clean(&level_editor->goals_layer); - rect_layer_clean(&level_editor->lava_layer); - rect_layer_clean(&level_editor->back_platforms_layer); - rect_layer_clean(&level_editor->boxes_layer); - label_layer_clean(&level_editor->label_layer); - rect_layer_clean(&level_editor->regions_layer); - undo_history_clean(&level_editor->undo_history); -} - -void destroy_level_editor(LevelEditor *level_editor) -{ - trace_assert(level_editor); - destroy_undo_history(level_editor->undo_history); - destroy_rect_layer(level_editor->boxes_layer); - destroy_rect_layer(level_editor->platforms_layer); - destroy_rect_layer(level_editor->back_platforms_layer); - destroy_point_layer(level_editor->goals_layer); - destroy_rect_layer(level_editor->lava_layer); - destroy_rect_layer(level_editor->regions_layer); - destroy_label_layer(level_editor->label_layer); - - if (level_editor->file_name) { - free(level_editor->file_name); - } + level_editor->player_layer = chop_player_layer(memory, &input); + rect_layer_load(level_editor->platforms_layer, memory, &input); + point_layer_load(level_editor->goals_layer, memory, &input); + rect_layer_load(level_editor->lava_layer, memory, &input); + rect_layer_load(level_editor->back_platforms_layer, memory, &input); + rect_layer_load(level_editor->boxes_layer, memory, &input); + label_layer_load(level_editor->label_layer, memory, &input); + rect_layer_load(level_editor->regions_layer, memory, &input); + undo_history_clean(level_editor->undo_history); + + return level_editor; } int level_editor_render(const LevelEditor *level_editor, @@ -218,7 +190,8 @@ int level_editor_render(const LevelEditor *level_editor, static int level_editor_saveas_event(LevelEditor *level_editor, const SDL_Event *event, - const Camera *camera) + const Camera *camera, + Memory *memory) { trace_assert(level_editor); trace_assert(event); @@ -234,7 +207,7 @@ int level_editor_saveas_event(LevelEditor *level_editor, LEVEL_FOLDER_MAX_LENGTH, "./assets/levels/%s.txt", edit_field_as_text(&level_editor->edit_field_filename)); - level_editor->file_name = string_duplicate(path, NULL); + level_editor->file_name = strdup_to_memory(memory, path); level_editor_dump(level_editor); SDL_StopTextInput(); level_editor->state = LEVEL_EDITOR_IDLE; @@ -272,10 +245,10 @@ int level_editor_idle_event(LevelEditor *level_editor, case SDLK_z: { if (event->key.keysym.mod & KMOD_CTRL) { - if (undo_history_empty(&level_editor->undo_history)) { + if (undo_history_empty(level_editor->undo_history)) { level_editor->bell = 1; } - undo_history_pop(&level_editor->undo_history); + undo_history_pop(level_editor->undo_history); } } break; } @@ -342,7 +315,7 @@ int level_editor_idle_event(LevelEditor *level_editor, level_editor->layers[level_editor->layer_picker], event, camera, - &level_editor->undo_history) < 0) { + level_editor->undo_history) < 0) { return -1; } } else { @@ -355,7 +328,8 @@ int level_editor_idle_event(LevelEditor *level_editor, int level_editor_event(LevelEditor *level_editor, const SDL_Event *event, - Camera *camera) + Camera *camera, + Memory *memory) { trace_assert(level_editor); trace_assert(event); @@ -366,7 +340,7 @@ int level_editor_event(LevelEditor *level_editor, return level_editor_idle_event(level_editor, event, camera); case LEVEL_EDITOR_SAVEAS: - return level_editor_saveas_event(level_editor, event, camera); + return level_editor_saveas_event(level_editor, event, camera, memory); } return 0; diff --git a/src/game/level/level_editor.h b/src/game/level/level_editor.h index 3750e748..07f36d56 100644 --- a/src/game/level/level_editor.h +++ b/src/game/level/level_editor.h @@ -27,19 +27,19 @@ struct LevelEditor LayerPicker layer_picker; FadingWigglyText notice; - RectLayer boxes_layer; - RectLayer platforms_layer; - RectLayer back_platforms_layer; - PointLayer goals_layer; + RectLayer *boxes_layer; + RectLayer *platforms_layer; + RectLayer *back_platforms_layer; + PointLayer *goals_layer; PlayerLayer player_layer; - RectLayer lava_layer; - RectLayer regions_layer; + RectLayer *lava_layer; + RectLayer *regions_layer; BackgroundLayer background_layer; - LabelLayer label_layer; + LabelLayer *label_layer; LayerPtr layers[LAYER_PICKER_N]; - UndoHistory undo_history; + UndoHistory *undo_history; bool drag; int bell; @@ -49,16 +49,15 @@ struct LevelEditor char *file_name; }; -void create_level_editor(LevelEditor *level_editor, Cursor *cursor); -void level_editor_load_from_file(LevelEditor *level_editor, Memory *tmpmem, const char *file_name); -void level_editor_clean(LevelEditor *level_editor); -void destroy_level_editor(LevelEditor *level_editor); +LevelEditor *create_level_editor_from_memory(Memory *memory, Cursor *cursor); +LevelEditor *create_level_editor_from_file_with_memory(Memory *memory, Cursor *cursor, const char *file_name); int level_editor_render(const LevelEditor *level_editor, const Camera *camera); int level_editor_event(LevelEditor *level_editor, const SDL_Event *event, - Camera *camera); + Camera *camera, + Memory *memory); int level_editor_focus_camera(LevelEditor *level_editor, Camera *camera); int level_editor_update(LevelEditor *level_editor, float delta_time); diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index b4fa6502..f28ceab5 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -156,7 +156,27 @@ LabelLayer create_label_layer(const char *id_name_prefix) return result; } -void label_layer_reload(LabelLayer *label_layer, +LabelLayer *create_label_layer_from_memory(Memory *memory, + const char *id_name_prefix) +{ + trace_assert(memory); + trace_assert(id_name_prefix); + + LabelLayer *result = memory_alloc(memory, sizeof(LabelLayer)); + memset(result, 0, sizeof(LabelLayer)); + result->ids = create_dynarray_from_memory(memory, sizeof(char) * LABEL_LAYER_ID_MAX_SIZE); + result->positions = create_dynarray_from_memory(memory, sizeof(Vec2f)); + result->colors = create_dynarray_from_memory(memory, sizeof(Color)); + result->texts = create_dynarray_from_memory(memory, sizeof(char) * LABEL_LAYER_TEXT_MAX_SIZE); + result->color_picker = create_color_picker_from_rgba(COLOR_RED); + result->selection = -1; + result->edit_field.font_size = LABELS_SIZE; + result->edit_field.font_color = COLOR_RED; + result->id_name_prefix = id_name_prefix; + return result; +} + +void label_layer_load(LabelLayer *label_layer, Memory *memory, String *input) { @@ -164,8 +184,6 @@ void label_layer_reload(LabelLayer *label_layer, trace_assert(memory); trace_assert(input); - label_layer_clean(label_layer); - int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n')))); char id[LABEL_LAYER_ID_MAX_SIZE]; char label_text[LABEL_LAYER_TEXT_MAX_SIZE]; @@ -200,15 +218,6 @@ void label_layer_reload(LabelLayer *label_layer, } } -void label_layer_clean(LabelLayer *label_layer) -{ - trace_assert(label_layer); - dynarray_clear(&label_layer->ids); - dynarray_clear(&label_layer->positions); - dynarray_clear(&label_layer->colors); - dynarray_clear(&label_layer->texts); -} - static inline Rect boundary_of_element(const LabelLayer *label_layer, size_t i, diff --git a/src/game/level/level_editor/label_layer.h b/src/game/level/level_editor/label_layer.h index 718a57f4..ee91f0a1 100644 --- a/src/game/level/level_editor/label_layer.h +++ b/src/game/level/level_editor/label_layer.h @@ -41,10 +41,10 @@ LayerPtr label_layer_as_layer(LabelLayer *label_layer); // NOTE: create_label_layer and create_label_layer_from_line_stream do // not own id_name_prefix LabelLayer create_label_layer(const char *id_name_prefix); -void label_layer_reload(LabelLayer *label_layer, +LabelLayer *create_label_layer_from_memory(Memory *memory, const char *id_name_prefix); +void label_layer_load(LabelLayer *label_layer, Memory *memory, String *input); -void label_layer_clean(LabelLayer *label_layer); static inline void destroy_label_layer(LabelLayer label_layer) diff --git a/src/game/level/level_editor/point_layer.c b/src/game/level/level_editor/point_layer.c index 735c3240..56d7318c 100644 --- a/src/game/level/level_editor/point_layer.c +++ b/src/game/level/level_editor/point_layer.c @@ -152,16 +152,32 @@ PointLayer create_point_layer(const char *id_name_prefix) return result; } -void point_layer_reload(PointLayer *point_layer, - Memory *memory, - String *input) +PointLayer *create_point_layer_from_memory(Memory *memory, + const char *id_name_prefix) +{ + trace_assert(memory); + trace_assert(id_name_prefix); + + PointLayer *result = memory_alloc(memory, sizeof(PointLayer)); + memset(result, 0, sizeof(PointLayer)); + result->state = POINT_LAYER_IDLE; + result->positions = create_dynarray_from_memory(memory, sizeof(Vec2f)); + result->colors = create_dynarray_from_memory(memory, sizeof(Color)); + result->ids = create_dynarray_from_memory(memory, sizeof(char) * ID_MAX_SIZE); + result->edit_field.font_size = POINT_LAYER_ID_TEXT_SIZE; + result->edit_field.font_color = POINT_LAYER_ID_TEXT_COLOR; + result->id_name_prefix = id_name_prefix; + return result; +} + +void point_layer_load(PointLayer *point_layer, + Memory *memory, + String *input) { trace_assert(point_layer); trace_assert(memory); trace_assert(input); - point_layer_clean(point_layer); - int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n')))); char id[ENTITY_MAX_ID_SIZE]; for (int i = 0; i < n; ++i) { @@ -181,14 +197,6 @@ void point_layer_reload(PointLayer *point_layer, } } -void point_layer_clean(PointLayer *point_layer) -{ - trace_assert(point_layer); - dynarray_clear(&point_layer->positions); - dynarray_clear(&point_layer->colors); - dynarray_clear(&point_layer->ids); -} - static inline Triangle element_shape(Vec2f position, float scale) { diff --git a/src/game/level/level_editor/point_layer.h b/src/game/level/level_editor/point_layer.h index 0505fb7e..1869a9f2 100644 --- a/src/game/level/level_editor/point_layer.h +++ b/src/game/level/level_editor/point_layer.h @@ -38,11 +38,10 @@ LayerPtr point_layer_as_layer(PointLayer *point_layer); // NOTE: create_point_layer and create_point_layer_from_line_stream do // not own id_name_prefix PointLayer create_point_layer(const char *id_name_prefix); -void point_layer_reload(PointLayer *point_layer, +PointLayer *create_point_layer_from_memory(Memory *memory, const char *id_name_prefix); +void point_layer_load(PointLayer *point_layer, Memory *memory, String *input); -void point_layer_clean(PointLayer *point_layer); - static inline void destroy_point_layer(PointLayer point_layer) diff --git a/src/game/level/level_editor/rect_layer.c b/src/game/level/level_editor/rect_layer.c index 447ecf77..f18b9bb3 100644 --- a/src/game/level/level_editor/rect_layer.c +++ b/src/game/level/level_editor/rect_layer.c @@ -796,34 +796,36 @@ LayerPtr rect_layer_as_layer(RectLayer *rect_layer) return layer; } -RectLayer create_rect_layer(const char *id_name_prefix, Cursor *cursor) +RectLayer *create_rect_layer_from_memory(Memory *memory, + const char *id_name_prefix, + Cursor *cursor) { + trace_assert(memory); + trace_assert(id_name_prefix); trace_assert(cursor); - RectLayer result = {0}; + RectLayer *rect_layer = memory_alloc(memory, sizeof(RectLayer)); - result.ids = create_dynarray(sizeof(char) * ENTITY_MAX_ID_SIZE); - result.rects = create_dynarray(sizeof(Rect)); - result.colors = create_dynarray(sizeof(Color)); - result.actions = create_dynarray(sizeof(Action)); - result.id_edit_field.font_size = RECT_LAYER_ID_LABEL_SIZE; - result.id_edit_field.font_color = COLOR_BLACK; - result.color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f)); - result.selection = -1; - result.id_name_prefix = id_name_prefix; - result.cursor = cursor; + rect_layer->ids = create_dynarray_from_memory(memory, sizeof(char) * ENTITY_MAX_ID_SIZE); + rect_layer->rects = create_dynarray_from_memory(memory, sizeof(Rect)); + rect_layer->colors = create_dynarray_from_memory(memory, sizeof(Color)); + rect_layer->actions = create_dynarray_from_memory(memory, sizeof(Action)); + rect_layer->id_edit_field.font_size = RECT_LAYER_ID_LABEL_SIZE; + rect_layer->id_edit_field.font_color = COLOR_BLACK; + rect_layer->color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f)); + rect_layer->selection = -1; + rect_layer->id_name_prefix = id_name_prefix; + rect_layer->cursor = cursor; - return result; + return rect_layer; } -void rect_layer_reload(RectLayer *layer, Memory *memory, String *input) +void rect_layer_load(RectLayer *layer, Memory *memory, String *input) { trace_assert(layer); trace_assert(memory); trace_assert(input); - rect_layer_clean(layer); - int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n')))); char id[ENTITY_MAX_ID_SIZE]; for (int i = 0; i < n; ++i) { @@ -876,15 +878,6 @@ void rect_layer_reload(RectLayer *layer, Memory *memory, String *input) } } -void rect_layer_clean(RectLayer *rect_layer) -{ - trace_assert(rect_layer); - dynarray_clear(&rect_layer->ids); - dynarray_clear(&rect_layer->rects); - dynarray_clear(&rect_layer->colors); - dynarray_clear(&rect_layer->actions); -} - int rect_layer_render(const RectLayer *layer, const Camera *camera, int active) { trace_assert(layer); diff --git a/src/game/level/level_editor/rect_layer.h b/src/game/level/level_editor/rect_layer.h index 682ab33e..73d95fdb 100644 --- a/src/game/level/level_editor/rect_layer.h +++ b/src/game/level/level_editor/rect_layer.h @@ -45,10 +45,11 @@ struct RectLayer { LayerPtr rect_layer_as_layer(RectLayer *layer); // NOTE: create_rect_layer and create_rect_layer_from_line_stream does // not own id_name_prefix -RectLayer create_rect_layer(const char *id_name_prefix, - Cursor *cursor); -void rect_layer_reload(RectLayer *rect_layer, Memory *memory, String *input); -void rect_layer_clean(RectLayer *rect_layer); + +RectLayer *create_rect_layer_from_memory(Memory *memory, + const char *id_name_prefix, + Cursor *cursor); +void rect_layer_load(RectLayer *rect_layer, Memory *memory, String *input); static inline void destroy_rect_layer(RectLayer layer) diff --git a/src/game/level/level_editor/undo_history.c b/src/game/level/level_editor/undo_history.c index 19096863..f1e933ff 100644 --- a/src/game/level/level_editor/undo_history.c +++ b/src/game/level/level_editor/undo_history.c @@ -14,19 +14,14 @@ typedef struct { size_t context_data_size; } HistoryItem; -static -void undo_history_destroy_item(void *item) +UndoHistory *create_undo_history_from_memory(Memory *memory) { - free(((HistoryItem*)item)->context_data); -} - -UndoHistory create_undo_history(void) -{ - UndoHistory result; - result.actions = create_ring_buffer( + UndoHistory *result = memory_alloc(memory, sizeof(UndoHistory)); + result->actions = create_ring_buffer_from_buffer( + memory, sizeof(HistoryItem), - UNDO_HISTORY_CAPACITY, - undo_history_destroy_item); + UNDO_HISTORY_CAPACITY); + result->memory = memory; return result; } @@ -37,14 +32,13 @@ void undo_history_push(UndoHistory *undo_history, { trace_assert(undo_history); + // TODO: undo_history_push kinda leaks the memory HistoryItem item = { .revert = revert, - .context_data = malloc(context_data_size), + .context_data = memory_alloc(undo_history->memory, context_data_size), .context_data_size = context_data_size }; - trace_assert(item.context_data); memcpy(item.context_data, context_data, context_data_size); - ring_buffer_push(&undo_history->actions, &item); } diff --git a/src/game/level/level_editor/undo_history.h b/src/game/level/level_editor/undo_history.h index 061d55e9..3a63fd30 100644 --- a/src/game/level/level_editor/undo_history.h +++ b/src/game/level/level_editor/undo_history.h @@ -7,15 +7,10 @@ typedef void (*RevertAction)(void *context, size_t context_size); typedef struct { RingBuffer actions; + Memory *memory; } UndoHistory; -UndoHistory create_undo_history(void); - -static inline -void destroy_undo_history(UndoHistory undo_history) -{ - destroy_ring_buffer(undo_history.actions); -} +UndoHistory *create_undo_history_from_memory(Memory *memory); void undo_history_push(UndoHistory *undo_history, RevertAction revert, diff --git a/src/ring_buffer.c b/src/ring_buffer.c index 905d1773..139b8c5f 100644 --- a/src/ring_buffer.c +++ b/src/ring_buffer.c @@ -16,7 +16,6 @@ void ring_buffer_push(RingBuffer *buffer, buffer->element_size); buffer->count += 1; } else { - if (buffer->dtor) buffer->dtor(buffer->data + i * buffer->element_size); memcpy( buffer->data + i * buffer->element_size, element, @@ -30,12 +29,6 @@ int ring_buffer_pop(RingBuffer *buffer) trace_assert(buffer); if (buffer->count == 0) return 0; - - if (buffer->dtor) { - size_t i = (buffer->begin + buffer->count - 1) % buffer->capacity; - buffer->dtor(buffer->data + i * buffer->element_size); - } - buffer->count--; return 1; diff --git a/src/ring_buffer.h b/src/ring_buffer.h index acb86e24..8728e216 100644 --- a/src/ring_buffer.h +++ b/src/ring_buffer.h @@ -15,28 +15,20 @@ typedef struct { size_t count; size_t begin; uint8_t *data; - RingBufferDtor dtor; } RingBuffer; static inline -RingBuffer create_ring_buffer(size_t element_size, - size_t capacity, - RingBufferDtor dtor) +RingBuffer create_ring_buffer_from_buffer(Memory *memory, + size_t element_size, + size_t capacity) { RingBuffer result = {0}; result.element_size = element_size; result.capacity = capacity; - result.dtor = dtor; - result.data = malloc(result.element_size * result.capacity); + result.data = memory_alloc(memory, result.element_size * result.capacity); return result; } -static inline -void destroy_ring_buffer(RingBuffer buffer) -{ - free(buffer.data); -} - void ring_buffer_push(RingBuffer *buffer, void *element); int ring_buffer_pop(RingBuffer *buffer); void *ring_buffer_top(RingBuffer *buffer); diff --git a/src/system/memory.h b/src/system/memory.h index c12c8e47..3dcc2e30 100644 --- a/src/system/memory.h +++ b/src/system/memory.h @@ -20,7 +20,6 @@ void *memory_alloc(Memory *memory, size_t size) assert(memory); assert(memory->size + size <= memory->capacity); - void *result = memory->buffer + memory->size; memory->size += size; diff --git a/src/system/s.h b/src/system/s.h index 43ff261c..aa7b4b40 100644 --- a/src/system/s.h +++ b/src/system/s.h @@ -120,4 +120,16 @@ char *string_to_cstr(Memory *memory, String s) return result; } +static inline +char *strdup_to_memory(Memory *memory, const char *s) +{ + trace_assert(memory); + trace_assert(s); + + const size_t n = strlen(s) + 1; + char *d = memory_alloc(memory, n); + memcpy(d, s, n); + return d; +} + #endif // S_H_ -- 2.44.0