Update Entity Manager component management

Changelog:
- Store entity idx for component map as key. This allows reference
  to the entity for related components in a system
- Modify systems to iterate over components instead following the
  above change. This follows closer to the intended ECS architecture
scene_man
En Yi 2023-01-05 21:09:06 +08:00
parent 3c02068ca6
commit 25870309c0
3 changed files with 32 additions and 20 deletions

View File

@ -97,6 +97,13 @@ void remove_entity(EntityManager_t *p_manager, unsigned long id)
sc_queue_add_last(&p_manager->to_remove, id);
}
Entity_t *get_entity(EntityManager_t *p_manager, unsigned long id)
{
Entity_t *p_entity = sc_map_get_64v(&p_manager->entities, id);
if(!sc_map_found(&p_manager->entities)) return NULL;
return p_entity;
}
// Components are not expected to be removed
// So, no need to extra steps to deal with iterator invalidation
void *add_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentEnum_t comp_type)
@ -107,7 +114,7 @@ void *add_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentEnu
if (p_comp)
{
sc_map_put_64(&p_entity->components, comp_type_idx, comp_idx);
sc_map_put_64v(&p_manager->component_map[comp_type_idx], comp_idx, p_comp);
sc_map_put_64v(&p_manager->component_map[comp_type_idx], p_entity->m_id, p_comp);
}
return p_comp;
}
@ -115,9 +122,10 @@ void *add_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentEnu
void *get_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentEnum_t comp_type)
{
unsigned long comp_type_idx = (unsigned long)comp_type;
unsigned long comp_idx = sc_map_get_64(&p_entity->components, comp_type_idx);
if (!sc_map_found(&p_entity->components)) return NULL;
return sc_map_get_64v(&p_manager->component_map[comp_type_idx], comp_idx);
void * p_comp = sc_map_get_64v(&p_manager->component_map[comp_type_idx], p_entity->m_id);
//unsigned long comp_idx = sc_map_get_64(&p_entity->components, comp_type_idx);
if (!sc_map_found(&p_manager->component_map[comp_type_idx])) return NULL;
return p_comp;
}
void remove_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentEnum_t comp_type)
@ -125,6 +133,6 @@ void remove_component(EntityManager_t *p_manager, Entity_t *p_entity, ComponentE
unsigned long comp_type_idx = (unsigned long)comp_type;
unsigned long comp_idx = sc_map_del_64(&p_entity->components, comp_type_idx);
if (!sc_map_found(&p_entity->components)) return;
sc_map_del_64v(&p_manager->component_map[comp_type_idx], comp_idx);
sc_map_del_64v(&p_manager->component_map[comp_type_idx], p_entity->m_id);
free_component_to_mempool(comp_type, comp_idx);
}

View File

@ -21,6 +21,7 @@ void free_entity_manager(EntityManager_t *p_manager);
Entity_t *add_entity(EntityManager_t *p_manager, EntityTag_t tag);
void remove_entity(EntityManager_t *p_manager, unsigned long id);
Entity_t *get_entity(EntityManager_t *p_manager, unsigned long id);
void *add_component(EntityManager_t *p_manager, Entity_t *entity, ComponentEnum_t comp_type);
void *get_component(EntityManager_t *p_manager, Entity_t *entity, ComponentEnum_t comp_type);

View File

@ -421,12 +421,11 @@ static void movement_update_system(Scene_t* scene)
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
// Update movement
float delta_time = 0.017; // TODO: Will need to think about delta time handling
//CTransform_t * p_ctransform;
Entity_t* p_ent;
//sc_map_foreach_value(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], p_ctransform)
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
CTransform_t * p_ctransform;
unsigned long ent_idx;
sc_map_foreach(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], ent_idx, p_ctransform)
{
CTransform_t * p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T);
Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx);
CBBox_t * p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T);
if (p_ctransform == NULL) continue;
@ -619,13 +618,16 @@ static void player_collision_system(Scene_t *scene)
static void state_transition_update_system(Scene_t *scene)
{
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
Entity_t* p_ent;
//sc_map_foreach_value(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], p_ctransform)
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
//Entity_t* p_ent;
CBBox_t *p_bbox;
unsigned long ent_idx;
sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox)
{
CTransform_t * p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T);
CBBox_t * p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T);
if (p_bbox == NULL) continue;
Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx);
CTransform_t *p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T);
if (p_ctransform == NULL) continue;
bool on_ground = check_on_ground(p_ctransform->position, p_bbox->size, &data->tilemap);
bool in_water = false;
if (!(p_ctransform->water_state & 1))
@ -667,11 +669,11 @@ static void update_tilemap_system(Scene_t *scene)
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
TileGrid_t tilemap = data->tilemap;
Entity_t *p_ent;
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
CTileCoord_t *p_tilecoord;
unsigned long ent_idx;
sc_map_foreach(&scene->ent_manager.component_map[CTILECOORD_COMP_T], ent_idx, p_tilecoord)
{
CTileCoord_t * p_tilecoord = get_component(&scene->ent_manager, p_ent, CTILECOORD_COMP_T);
if (p_tilecoord == NULL) continue;
Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx);
CTransform_t * p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T);
if (p_ctransform == NULL) continue;
CBBox_t * p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T);
@ -708,6 +710,7 @@ static void update_tilemap_system(Scene_t *scene)
static void toggle_block_system(Scene_t *scene)
{
// TODO: This system is not good as the interface between raw input and actions is broken
static unsigned int last_tile_idx = MAX_N_TILES;
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
TileGrid_t tilemap = data->tilemap;