#define TMPMEM_CAPACITY (640 * KILO)
+#define LEVEL_EDITOR_MEMORY_CAPACITY (640 * KILO)
+
#endif // CONFIG_H_
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);
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;
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);
}
}
- 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,
{
trace_assert(game);
destroy_level_picker(game->level_picker);
- free(game->tmpmem.buffer);
+ free(game->level_editor_memory.buffer);
RETURN_LT0(game->lt);
}
} 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;
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:
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: {
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;
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) {
game->lt,
game->level,
create_level_from_level_editor(
- &game->level_editor));
+ game->level_editor));
if (game->level == NULL) {
return -1;
}
} 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)
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) {
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);
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);
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);
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);
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);
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);
level->regions = PUSH_LT(
lt,
create_regions_from_rect_layer(
- &level_editor->regions_layer,
+ level_editor->regions_layer,
level->labels,
level->goals),
destroy_regions);
// 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;
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 = {
};
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'));
// 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,
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);
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;
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;
}
level_editor->layers[level_editor->layer_picker],
event,
camera,
- &level_editor->undo_history) < 0) {
+ level_editor->undo_history) < 0) {
return -1;
}
} else {
int level_editor_event(LevelEditor *level_editor,
const SDL_Event *event,
- Camera *camera)
+ Camera *camera,
+ Memory *memory)
{
trace_assert(level_editor);
trace_assert(event);
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;
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;
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);
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)
{
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];
}
}
-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,
// 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)
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) {
}
}
-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)
{
// 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)
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) {
}
}
-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);
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)
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;
}
{
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);
}
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,
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,
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;
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);
assert(memory);
assert(memory->size + size <= memory->capacity);
-
void *result = memory->buffer + memory->size;
memory->size += size;
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_