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 ?)

This commit is contained in:
Ulysse Cura 2026-05-08 14:20:11 +02:00
parent d3ce988aaf
commit 53ae1f59d3
8 changed files with 47 additions and 78 deletions

View File

@ -5,9 +5,9 @@
// Args : size_t nb_frames, size_t actual_frame, float frame_delay_ms, bool play, bool loop, bool reverse // 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) 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->nb_frames = va_arg(args, size_t);
system_data->actual_frame_nb= 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) 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) if(system_data->play)
{ {
@ -77,8 +77,10 @@ void animation_system_update(component_t *component)
inline void animation_system_destroy(component_t *component) inline void animation_system_destroy(component_t *component)
{ {
linked_list_clear(&component->component_data.animation_system_data->frames); animation_system_data_t *system_data = component->component_data;
free(component->component_data.animation_system_data);
linked_list_clear(&system_data->frames);
free(system_data);
} }
void animation_system_create_frames_clips(animation_system_data_t *system_data) void animation_system_create_frames_clips(animation_system_data_t *system_data)

View File

@ -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

View File

@ -2,6 +2,9 @@
#define PLAYER_SYSTEM_H #define PLAYER_SYSTEM_H
#include "ecs.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_SPEED 80.0f // px / s
#define PLAYER_DEFAULT_IDLE_ANIMATION_SPEED 250.0f // ms / frame #define PLAYER_DEFAULT_IDLE_ANIMATION_SPEED 250.0f // ms / frame

View File

@ -8,9 +8,9 @@
// No args // No args
void player_system_init(component_t *component, va_list args __attribute__((unused))) 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->sprite_component_data = system_data->animation_system_data->sprite_component_data;
system_data->transform_component_data = system_data->sprite_component_data->transform_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) 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_get_inputs(system_data);
player_system_set_velocity(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) void player_system_destroy(component_t *component)
{ {
free(component->component_data.player_system_data); free(component->component_data);
} }

View File

@ -5,9 +5,9 @@
// Arg : const char *name // Arg : const char *name
void sprite_component_init(component_t *component, va_list args) 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); frect_to_rect(&component_data->transform_component_data->bounds, &component_data->src_rect);
component_data->src_rect.x = 0; 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) 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); frect_to_rect(&component_data->transform_component_data->bounds, &component_data->dst_rect);
} }
inline void sprite_component_draw(component_t *component) 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); draw_texture(component_data->texture, &component_data->src_rect, &component_data->dst_rect, component_data->flip);
} }
inline void sprite_component_destroy(component_t *component) 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) inline void sprite_component_set_texture(sprite_component_data_t *component_data, const char *name)

View File

@ -5,7 +5,7 @@
// Args : frect_t bounds, double speed // Args : frect_t bounds, double speed
void transform_component_init(component_t *component, va_list args) 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->bounds = va_arg(args, frect_t);
component_data->speed = (float)va_arg(args, double); 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) 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.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; 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) inline void transform_component_destroy(component_t *component)
{ {
free(component->component_data.transform_component_data); free(component->component_data);
} }

View File

@ -10,53 +10,19 @@ component_t *create_component(component_type_t component_type)
switch(component_type) switch(component_type)
{ {
case TRANSFORM_COMPONENT: #define COMPONENT(NAME, PREFIX, DRAW) \
component->component_init = transform_component_init; case NAME: \
component->component_update = transform_component_update; component->component_init = PREFIX##_init; \
component->component_draw = NULL; component->component_update = PREFIX##_update; \
component->component_draw = DRAW(PREFIX); \
component->component_data.transform_component_data = malloc(sizeof(transform_component_data_t)); component->component_data = malloc(sizeof(PREFIX##_data_t)); \
if(!component->component_data.transform_component_data) return NULL; if(!component->component_data){ free(component); return NULL; } \
component->component_deleter = PREFIX##_destroy; \
component->component_deleter = transform_component_destroy;
break; break;
#include "components.def"
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
default: default:
free(component);
return NULL; return NULL;
} }

View File

@ -6,19 +6,11 @@
#include "linked_list.h" #include "linked_list.h"
typedef enum component_type_t { typedef enum component_type_t {
TRANSFORM_COMPONENT, #define COMPONENT(NAME, PREFIX, DRAW) NAME,
SPRITE_COMPONENT, #include "components.def"
ANIMATION_SYSTEM,
PLAYER_SYSTEM,
// Add new components types here
} component_type_t; } component_type_t;
// Structs forwarding // Component 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;
typedef struct component_t component_t; typedef struct component_t component_t;
// Component init function. It is called when component added to entity. This function is necessary. // 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_update_t component_update;
component_draw_t component_draw; component_draw_t component_draw;
union { void *component_data;
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;
component_deleter_t component_deleter; component_deleter_t component_deleter;