#include #include #include "ecs.h" #include "components.h" component_t *create_component(component_type_t component_type) { component_t *component = kmalloc(sizeof(component_t), NULL); component->component_type = 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 = kmalloc(sizeof(transform_component_data_t), NULL); if(!component->component_data.transform_component_data) return NULL; component->component_deleter = transform_component_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 = kmalloc(sizeof(sprite_component_data_t), NULL); 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 = kmalloc(sizeof(animation_system_data_t), NULL); 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 = kmalloc(sizeof(player_system_data_t), NULL); if(!component->component_data.player_system_data) return NULL; component->component_deleter = player_system_destroy; break; // Add new components attributions here default: return NULL; } return component; } inline void destroy_component(component_t *component) { component->component_deleter(component); kfree(component); } entity_t *create_entity(const char *name) { entity_t *entity = kmalloc(sizeof(entity_t), NULL); if(!entity) return NULL; entity->name = name; entity->draw_priority = 0; linked_list_init(&entity->components, sizeof(component_t), (deleter_t)destroy_component); return entity; } void add_component(entity_t *entity, component_t *component, ...) { if(!component) return; component->entity = entity; va_list args, args_copy; va_start(args, component); va_copy(args_copy, args); component->component_init(component, args_copy); va_end(args_copy); va_end(args); linked_list_push_back(&entity->components, component); } // Only for this file // Arg : component_type_t component_type static inline bool condition_is_component_type(elem_t *elem, va_list args) { return ((component_t *)elem->data)->component_type == va_arg(args, component_type_t); } inline component_t *get_component(entity_t *entity, component_type_t component_type) { return linked_list_get_if(&entity->components, condition_is_component_type, component_type); } // Only for this file // No args static inline void action_update_component(elem_t *elem, va_list args __attribute__((unused))) { component_t *component = elem->data; component->component_update(component); } inline void update_entity(entity_t *entity) { linked_list_for_each(&entity->components, action_update_component); } // Only for this file // No args static inline void action_draw_component(elem_t *elem, va_list args __attribute__((unused))) { component_t *component = elem->data; if(component->component_draw) component->component_draw(component); } inline void draw_entity(entity_t *entity) { linked_list_for_each(&entity->components, action_draw_component); } inline void destroy_entity(entity_t *entity) { linked_list_clear(&entity->components); kfree(entity); } inline void entity_manager_init(entity_manager_t *entity_manager) { linked_list_init(&entity_manager->entities, sizeof(entity_t), (deleter_t)destroy_entity); } inline entity_t *entity_manager_add_entity(entity_manager_t *entity_manager, const char *name) { entity_t *entity = create_entity(name); linked_list_push_back(&entity_manager->entities, entity); return entity; } // Only for this file static inline void action_update_entity(elem_t *elem, va_list args __attribute__((unused))) { update_entity(elem->data); } inline void entity_manager_update(entity_manager_t *entity_manager) { linked_list_for_each(&entity_manager->entities, action_update_entity); } // Only for this file static inline void action_draw_entity(elem_t *elem, va_list args __attribute__((unused))) { draw_entity(elem->data); } inline void entity_manager_draw(entity_manager_t *entity_manager) { linked_list_for_each(&entity_manager->entities, action_draw_entity); } // Only for this file static inline bool condition_is_entity_name(elem_t *elem, va_list args) { return ((entity_t *)elem->data)->name == va_arg(args, const char *); } inline void entity_manager_remove_entity(entity_manager_t *entity_manager, const char *name) { linked_list_remove_if(&entity_manager->entities, condition_is_entity_name, name); } inline void entity_manager_clear(entity_manager_t *entity_manager) { linked_list_clear(&entity_manager->entities); }