From 53ae1f59d32fbe4cf03d2a2c89e58caaf7c885d6 Mon Sep 17 00:00:00 2001 From: Ulysse Cura Date: Fri, 8 May 2026 14:20:11 +0200 Subject: [PATCH] Externalised components definition, removed union for componant data because ugly and corrected a memory leak in the create_component function when quitting on error (maybe moving ecs.c into core later ?) --- src/ecs/components/animation_system.c | 12 +++-- src/ecs/components/headers/components.def | 11 +++++ src/ecs/components/headers/player_system.h | 3 ++ src/ecs/components/player_system.c | 8 ++-- src/ecs/components/sprite_component.c | 10 ++-- src/ecs/components/transform_component.c | 6 +-- src/ecs/ecs.c | 54 ++++------------------ src/ecs/headers/ecs.h | 21 ++------- 8 files changed, 47 insertions(+), 78 deletions(-) create mode 100644 src/ecs/components/headers/components.def diff --git a/src/ecs/components/animation_system.c b/src/ecs/components/animation_system.c index 76e12d7..9af0988 100644 --- a/src/ecs/components/animation_system.c +++ b/src/ecs/components/animation_system.c @@ -5,9 +5,9 @@ // Args : size_t nb_frames, size_t actual_frame, float frame_delay_ms, bool play, bool loop, bool reverse void animation_system_init(component_t *component, va_list args) { - animation_system_data_t *system_data = component->component_data.animation_system_data; + animation_system_data_t *system_data = component->component_data; - system_data->sprite_component_data = get_component(component->entity, SPRITE_COMPONENT)->component_data.sprite_component_data; + system_data->sprite_component_data = get_component(component->entity, SPRITE_COMPONENT)->component_data; system_data->nb_frames = va_arg(args, size_t); system_data->actual_frame_nb= va_arg(args, size_t); @@ -25,7 +25,7 @@ void animation_system_init(component_t *component, va_list args) void animation_system_update(component_t *component) { - animation_system_data_t *system_data = component->component_data.animation_system_data; + animation_system_data_t *system_data = component->component_data; if(system_data->play) { @@ -77,8 +77,10 @@ void animation_system_update(component_t *component) inline void animation_system_destroy(component_t *component) { - linked_list_clear(&component->component_data.animation_system_data->frames); - free(component->component_data.animation_system_data); + animation_system_data_t *system_data = component->component_data; + + linked_list_clear(&system_data->frames); + free(system_data); } void animation_system_create_frames_clips(animation_system_data_t *system_data) diff --git a/src/ecs/components/headers/components.def b/src/ecs/components/headers/components.def new file mode 100644 index 0000000..d2830e6 --- /dev/null +++ b/src/ecs/components/headers/components.def @@ -0,0 +1,11 @@ +// COMPONENT(NAME(STRING), PREFIX(STRING), DRAW(MACRO)) +#define DRAW(PREFIX) PREFIX##_draw +#define NO_DRAW(...) NULL + +COMPONENT(TRANSFORM_COMPONENT, transform_component, NO_DRAW) +COMPONENT(SPRITE_COMPONENT, sprite_component, DRAW) +COMPONENT(ANIMATION_SYSTEM, animation_system, NO_DRAW) +COMPONENT(PLAYER_SYSTEM, player_system, NO_DRAW) +// Add new components definition here + +#undef COMPONENT diff --git a/src/ecs/components/headers/player_system.h b/src/ecs/components/headers/player_system.h index 320f936..b983e6f 100644 --- a/src/ecs/components/headers/player_system.h +++ b/src/ecs/components/headers/player_system.h @@ -2,6 +2,9 @@ #define PLAYER_SYSTEM_H #include "ecs.h" +#include "transform_component.h" +#include "sprite_component.h" +#include "animation_system.h" #define PLAYER_DEFAULT_SPEED 80.0f // px / s #define PLAYER_DEFAULT_IDLE_ANIMATION_SPEED 250.0f // ms / frame diff --git a/src/ecs/components/player_system.c b/src/ecs/components/player_system.c index afaec80..43db7f5 100644 --- a/src/ecs/components/player_system.c +++ b/src/ecs/components/player_system.c @@ -8,9 +8,9 @@ // No args void player_system_init(component_t *component, va_list args __attribute__((unused))) { - player_system_data_t *system_data = component->component_data.player_system_data; + player_system_data_t *system_data = component->component_data; - system_data->animation_system_data = get_component(component->entity, ANIMATION_SYSTEM)->component_data.animation_system_data; + system_data->animation_system_data = get_component(component->entity, ANIMATION_SYSTEM)->component_data; system_data->sprite_component_data = system_data->animation_system_data->sprite_component_data; system_data->transform_component_data = system_data->sprite_component_data->transform_component_data; @@ -75,7 +75,7 @@ static inline void player_system_set_animation(player_system_data_t *system_data void player_system_update(component_t *component) { - player_system_data_t *system_data = component->component_data.player_system_data; + player_system_data_t *system_data = component->component_data; player_system_get_inputs(system_data); player_system_set_velocity(system_data); @@ -84,5 +84,5 @@ void player_system_update(component_t *component) void player_system_destroy(component_t *component) { - free(component->component_data.player_system_data); + free(component->component_data); } diff --git a/src/ecs/components/sprite_component.c b/src/ecs/components/sprite_component.c index 2280a0b..8ed8537 100644 --- a/src/ecs/components/sprite_component.c +++ b/src/ecs/components/sprite_component.c @@ -5,9 +5,9 @@ // Arg : const char *name void sprite_component_init(component_t *component, va_list args) { - sprite_component_data_t *component_data = component->component_data.sprite_component_data; + sprite_component_data_t *component_data = component->component_data; - component_data->transform_component_data = get_component(component->entity, TRANSFORM_COMPONENT)->component_data.transform_component_data; + component_data->transform_component_data = get_component(component->entity, TRANSFORM_COMPONENT)->component_data; frect_to_rect(&component_data->transform_component_data->bounds, &component_data->src_rect); component_data->src_rect.x = 0; @@ -20,19 +20,19 @@ void sprite_component_init(component_t *component, va_list args) inline void sprite_component_update(component_t *component) { - sprite_component_data_t *component_data = component->component_data.sprite_component_data; + sprite_component_data_t *component_data = component->component_data; frect_to_rect(&component_data->transform_component_data->bounds, &component_data->dst_rect); } inline void sprite_component_draw(component_t *component) { - sprite_component_data_t *component_data = component->component_data.sprite_component_data; + sprite_component_data_t *component_data = component->component_data; draw_texture(component_data->texture, &component_data->src_rect, &component_data->dst_rect, component_data->flip); } inline void sprite_component_destroy(component_t *component) { - free(component->component_data.sprite_component_data); + free(component->component_data); } inline void sprite_component_set_texture(sprite_component_data_t *component_data, const char *name) diff --git a/src/ecs/components/transform_component.c b/src/ecs/components/transform_component.c index 3be362e..ac63a9c 100644 --- a/src/ecs/components/transform_component.c +++ b/src/ecs/components/transform_component.c @@ -5,7 +5,7 @@ // Args : frect_t bounds, double speed void transform_component_init(component_t *component, va_list args) { - transform_component_data_t *const component_data = component->component_data.transform_component_data; + transform_component_data_t *const component_data = component->component_data; component_data->bounds = va_arg(args, frect_t); component_data->speed = (float)va_arg(args, double); @@ -16,7 +16,7 @@ void transform_component_init(component_t *component, va_list args) void transform_component_update(component_t *component) { - transform_component_data_t *component_data = component->component_data.transform_component_data; + transform_component_data_t *component_data = component->component_data; component_data->bounds.x += component_data->velocity.x * component_data->speed * (float)game.delta_time_ms / 1000.0f; component_data->bounds.y += component_data->velocity.y * component_data->speed * (float)game.delta_time_ms / 1000.0f; @@ -24,5 +24,5 @@ void transform_component_update(component_t *component) inline void transform_component_destroy(component_t *component) { - free(component->component_data.transform_component_data); + free(component->component_data); } diff --git a/src/ecs/ecs.c b/src/ecs/ecs.c index 3658d05..c548aa0 100644 --- a/src/ecs/ecs.c +++ b/src/ecs/ecs.c @@ -10,53 +10,19 @@ component_t *create_component(component_type_t component_type) switch(component_type) { - case TRANSFORM_COMPONENT: - component->component_init = transform_component_init; - component->component_update = transform_component_update; - component->component_draw = NULL; - - component->component_data.transform_component_data = malloc(sizeof(transform_component_data_t)); - if(!component->component_data.transform_component_data) return NULL; - - component->component_deleter = transform_component_destroy; +#define COMPONENT(NAME, PREFIX, DRAW) \ + case NAME: \ + component->component_init = PREFIX##_init; \ + component->component_update = PREFIX##_update; \ + component->component_draw = DRAW(PREFIX); \ + component->component_data = malloc(sizeof(PREFIX##_data_t)); \ + if(!component->component_data){ free(component); return NULL; } \ + component->component_deleter = PREFIX##_destroy; \ break; - - case SPRITE_COMPONENT: - component->component_init = sprite_component_init; - component->component_update = sprite_component_update; - component->component_draw = sprite_component_draw; - - component->component_data.sprite_component_data = malloc(sizeof(sprite_component_data_t)); - if(!component->component_data.sprite_component_data) return NULL; - - component->component_deleter = sprite_component_destroy; - break; - - case ANIMATION_SYSTEM: - component->component_init = animation_system_init; - component->component_update = animation_system_update; - component->component_draw = NULL; - - component->component_data.animation_system_data = malloc(sizeof(animation_system_data_t)); - if(!component->component_data.animation_system_data) return NULL; - - component->component_deleter = animation_system_destroy; - break; - - case PLAYER_SYSTEM: - component->component_init = player_system_init; - component->component_update = player_system_update; - component->component_draw = NULL; - - component->component_data.player_system_data = malloc(sizeof(player_system_data_t)); - if(!component->component_data.player_system_data) return NULL; - - component->component_deleter = player_system_destroy; - break; - - // Add new components attributions here +#include "components.def" default: + free(component); return NULL; } diff --git a/src/ecs/headers/ecs.h b/src/ecs/headers/ecs.h index 1144aa8..9c90d9a 100644 --- a/src/ecs/headers/ecs.h +++ b/src/ecs/headers/ecs.h @@ -6,19 +6,11 @@ #include "linked_list.h" typedef enum component_type_t { - TRANSFORM_COMPONENT, - SPRITE_COMPONENT, - ANIMATION_SYSTEM, - PLAYER_SYSTEM, - // Add new components types here +#define COMPONENT(NAME, PREFIX, DRAW) NAME, +#include "components.def" } component_type_t; -// Structs forwarding -typedef struct transform_component_data_t transform_component_data_t; -typedef struct sprite_component_data_t sprite_component_data_t; -typedef struct animation_system_data_t animation_system_data_t; -typedef struct player_system_data_t player_system_data_t; - +// Component forwarding typedef struct component_t component_t; // Component init function. It is called when component added to entity. This function is necessary. @@ -37,12 +29,7 @@ typedef struct component_t { component_update_t component_update; component_draw_t component_draw; - union { - transform_component_data_t *transform_component_data; - sprite_component_data_t *sprite_component_data; - animation_system_data_t *animation_system_data; - player_system_data_t *player_system_data; - } component_data; + void *component_data; component_deleter_t component_deleter;