#+private package ecs import "core:log" ComponentPool :: struct(Component: typeid) { data: []Component, entity_to_index: map[EntityID]uintptr, index_to_entity: map[uintptr]EntityID, size: uintptr, } component_pool_init :: proc(component_pool: ^ComponentPool($Component)) { component_pool.data = make([]Component, ENTITY_MAX, context.allocator) component_pool.entity_to_index = make(map[EntityID]uintptr, context.allocator) component_pool.index_to_entity = make(map[uintptr]EntityID, context.allocator) component_pool.size = 0 } component_pool_insert_data :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID, component: Component) { log.assertf(entity_id not_in component_pool.entity_to_index, "Component already added to entity") new_idx := component_pool.size component_pool.entity_to_index[entity_id] = new_idx component_pool.index_to_entity[new_idx] = entity_id component_pool.data[new_idx] = component component_pool.size += 1 } component_pool_remove_data :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) { log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component") removed_entity_idx := component_pool.entity_to_index[entity_id] last_element_idx := component_pool.size - 1 component_pool.data[removed_entity_idx] = component_pool.data[last_element_idx] last_element_entity_id := component_pool.index_to_entity[last_element_idx] component_pool.entity_to_index[last_element_entity_id] = removed_entity_idx component_pool.index_to_entity[removed_entity_idx] = last_element_entity_id delete_key(&component_pool.entity_to_index, entity_id) delete_key(&component_pool.index_to_entity, last_element_idx) component_pool.size -= 1 } component_pool_get :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) -> ^Component { log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component") idx := component_pool.entity_to_index[entity_id] return &component_pool.data[idx] } component_pool_destroy_entity :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) { if entity_id in component_pool.entity_to_index { component_pool_remove_data(component_pool, entity_id) } } component_pool_delete :: proc(component_pool: ^ComponentPool($Component)) { delete(component_pool.data) delete(component_pool.entity_to_index) delete(component_pool.index_to_entity) }