]> git.lizzy.rs Git - nothing.git/commitdiff
Try to remove malloc from LevelEditor
authorrexim <reximkut@gmail.com>
Sat, 11 Jan 2020 18:58:06 +0000 (01:58 +0700)
committerrexim <reximkut@gmail.com>
Sat, 11 Jan 2020 18:58:06 +0000 (01:58 +0700)
18 files changed:
src/config.h
src/dynarray.h
src/game.c
src/game/level.c
src/game/level/level_editor.c
src/game/level/level_editor.h
src/game/level/level_editor/label_layer.c
src/game/level/level_editor/label_layer.h
src/game/level/level_editor/point_layer.c
src/game/level/level_editor/point_layer.h
src/game/level/level_editor/rect_layer.c
src/game/level/level_editor/rect_layer.h
src/game/level/level_editor/undo_history.c
src/game/level/level_editor/undo_history.h
src/ring_buffer.c
src/ring_buffer.h
src/system/memory.h
src/system/s.h

index f26ea0d2564d3231ba2a21159cf3d007dc4fae88..6be65940a7dee1bd40a1f12fbc2e5998f11be742 100644 (file)
@@ -37,4 +37,6 @@
 
 #define TMPMEM_CAPACITY (640 * KILO)
 
+#define LEVEL_EDITOR_MEMORY_CAPACITY (640 * KILO)
+
 #endif  // CONFIG_H_
index 39bc1b9157383b92b1910e41b03312a96b7c1a6b..15f228f2831736ae90b5ada7e98d9f7bc39363bd 100644 (file)
@@ -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);
index d009528332486d6850404fb6abb5707874d11ecc..c8615c7238a38d6ccf90311e7159f15ab2cbee41 100644 (file)
@@ -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) {
index a65d621912ea56f4aea0532ea334d3227410af6d..eeb5b65478b93c2a4145b50a22b23eddec18bd23 100644 (file)
@@ -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);
index 0a434caec56b09df5e064160e142972db5069b43..f69d6adcff704b4352803f3b4c5393b5738364f6 100644 (file)
@@ -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;
index 3750e748cbf389a64c2ab02ae1c7086ee0b811dd..07f36d5696073db162a711d27ca0ca3942f21d49 100644 (file)
@@ -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);
index b4fa65022cdfb6c78ff2a8dd873a0607703b6f63..f28ceab51f5ab4aa63ef0443e2ef984ad6af5afa 100644 (file)
@@ -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,
index 718a57f44d960e8d044b5940e6fa3565bee2cedb..ee91f0a1fd81ecd5d733c23bb14840c7c4bbc4de 100644 (file)
@@ -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)
index 735c3240866bd206c75c43a200bf9abadc1e1945..56d7318c0541df25cdf521059a6ba158d0e984e2 100644 (file)
@@ -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)
 {
index 0505fb7ef1ce7db181d15b389511a48fc2cce6fb..1869a9f2bc26e00a95bc0cf76bf806598fecd406 100644 (file)
@@ -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)
index 447ecf7735ebe32d4006082c0387ffb203d2b76f..f18b9bb31a89e13601295acf44d4ed97318761c2 100644 (file)
@@ -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);
index 682ab33e072c0e8befe617953ecee9aca3987e9d..73d95fdb6969b51c3f1039c9ced631f50ff25d4d 100644 (file)
@@ -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)
index 1909686310d3b5de7ba8b3ea3a0c7d864163837f..f1e933ffd5bc6b267b99484ee770a05851444c61 100644 (file)
@@ -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);
 }
 
index 061d55e9ec9da5676ececfa344f3136eadb8c099..3a63fd30778ab5bffccdd89e142ceca4098d2aa5 100644 (file)
@@ -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,
index 905d1773637eb2a130417108d5cf5fe27868e538..139b8c5f120a45bc6e6ad9f9abd7e2bac8badd32 100644 (file)
@@ -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;
index acb86e247852b7927364cf5fcecd333a4bc9b46b..8728e21630d4b35890cef0cb139138170241ff39 100644 (file)
@@ -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);
index c12c8e47d662664ba3d0504ed150f644f169fcf2..3dcc2e309c800849dd1099caf360b3ccb1110b6f 100644 (file)
@@ -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;
 
index 43ff261cdf590ceb86b306d0c67926b483187ff0..aa7b4b401ccd6e7ed2083982322aaefe1fde7a7a 100644 (file)
@@ -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_