#include #include #include 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(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_allocate_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_allocate_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; }