This repository has been archived on 2024-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
MainTree/core/src-c/entity_registry.c

151 lines
3.9 KiB
C

#include <entity.h>
#include <librr/memory.h>
#include <stdlib.h>
MtEntityLookupTree mt_create_entity_lookup_tree();
void mt_delete_entity_lookup_tree(MtEntityLookupTree lookup_tree);
MtEntityRegistry mt_create_entity_registry()
{
MtEntityRegistry entity_registry;
entity_registry.lookup = mt_create_entity_lookup_tree();
entity_registry.pool = mt_create_entity_pool(16384);
entity_registry.entity_id_counter = 1;
return entity_registry;
}
void mt_delete_entity_registry(MtEntityRegistry *entity_registry)
{
mt_delete_entity_lookup_tree(entity_registry->lookup);
mt_delete_entity_pool(&entity_registry->pool);
}
MtEntityLookupTree mt_create_entity_lookup_tree()
{
MtEntityLookupTree lookup_tree;
rr_memset(&lookup_tree, sizeof(MtEntityLookupTree), 0x00);
return lookup_tree;
}
void mt_delete_entity_lookup_tree(MtEntityLookupTree lookup_tree)
{
usz_t level1_index = 0;
while(level1_index < 256)
{
if(lookup_tree.sublists[level1_index] == NULL)
{
++level1_index;
continue;
}
MtEntityListL1 *level1_list = lookup_tree.sublists[level1_index];
usz_t level2_index = 0;
while(level2_index < 256)
{
MtEntityListL2 *level2_list = level1_list->sublists[level2_index];
if(level2_list == NULL)
{
++level2_index;
continue;
}
usz_t level3_index = 0;
while(level3_index < 256)
{
MtEntityListL3 *level3_list = level2_list->sublists[level3_index];
if(level3_list == NULL)
{
++level3_index;
continue;
}
usz_t entity_index = 0;
while(entity_index < 256)
{
MtEntity entity = level3_list->entities[entity_index];
if(entity == NULL)
{
++entity_index;
continue;
}
mt_delete_entity_data(entity);
++entity_index;
}
free(level3_list);
++level3_index;
}
free(level2_list);
++level2_index;
}
free(level1_list);
++level1_index;
}
}
void mt_delete_entity_data(MtEntity entity)
{
if(entity->tags != NULL)
free(entity->tags);
}
void mt_reset_entity_pool_allocation(MtEntityPool *pool)
{
usz_t entity_index = 0;
while(entity_index < pool->capacity)
{
pool->entities[entity_index].pool_next_free = &pool->entities[entity_index+1];
++entity_index;
}
pool->entities[pool->capacity - 1].pool_next_free = NULL;
}
MtEntityPool mt_create_entity_pool(usz_t capacity)
{
MtEntityPool pool;
pool.capacity = capacity;
pool.entities = calloc(sizeof(struct MtEntity), pool.capacity);
mt_reset_entity_pool_allocation(&pool);
pool.first_free = &pool.entities[0];
pool.continuation = NULL;
return pool;
}
void mt_delete_entity_pool(MtEntityPool *pool)
{
if(pool->continuation != NULL)
{
mt_delete_entity_pool(pool->continuation);
free(pool->continuation);
}
free(pool->entities);
}
MtEntity mt_get_entity_pool_slot(MtEntityPool *pool)
{
if(pool->first_free == NULL)
{
if(pool->continuation == NULL)
{
pool->continuation = malloc(sizeof(MtEntityPool));
*pool->continuation = mt_create_entity_pool(pool->capacity * 2);
}
return mt_get_entity_pool_slot(pool->continuation);
}
MtEntity allocated = pool->first_free;
pool->first_free = allocated->pool_next_free;
return allocated;
}
void mt_give_back_entity_pool_slot(MtEntityPool *pool, MtEntity entity)
{
entity->pool_next_free = pool->first_free;
pool->first_free = entity;
}