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

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

View File

@ -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);
}

View File

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

View File

@ -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);
}

View File

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

View File

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