151 lines
3.9 KiB
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;
|
|
}
|