144 lines
3.6 KiB
C
144 lines
3.6 KiB
C
|
#include <entity.h>
|
||
|
#include <librr/memory.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
void mt_delete_entity(MtEntity entity);
|
||
|
|
||
|
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();
|
||
|
return entity_registry;
|
||
|
}
|
||
|
|
||
|
void mt_delete_entity_registry(MtEntityRegistry *entity_registry)
|
||
|
{
|
||
|
mt_delete_entity_pool(&entity_registry->pool);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
MtEntityLookupTree mt_create_entity_lookup_tree()
|
||
|
{
|
||
|
MtEntityLookupTree lookup_tree;
|
||
|
rr_memset(&lookup_tree.sublists[0], sizeof(MtEntityListL1 *) * 256, 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)
|
||
|
{
|
||
|
MtEntityListL3 *level3_list = level2_list->sublists[level3_index];
|
||
|
if(level3_list == NULL)
|
||
|
{
|
||
|
++level3_index;
|
||
|
continue;
|
||
|
}
|
||
|
usz_t entity_index = 0;
|
||
|
while(entity_index)
|
||
|
{
|
||
|
MtEntity entity = level3_list->entities[entity_index];
|
||
|
if(entity == NULL)
|
||
|
{
|
||
|
++entity_index;
|
||
|
continue;
|
||
|
}
|
||
|
mt_delete_entity(entity);
|
||
|
++entity_index;
|
||
|
}
|
||
|
free(level3_list);
|
||
|
++level3_index;
|
||
|
}
|
||
|
free(level2_list);
|
||
|
++level2_index;
|
||
|
}
|
||
|
free(level1_list);
|
||
|
++level1_index;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void mt_delete_entity(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;
|
||
|
}
|