88 lines
3.9 KiB
Odin
88 lines
3.9 KiB
Odin
#+private
|
|
package ecs
|
|
|
|
import "core:log"
|
|
|
|
ComponentManager :: struct {
|
|
component_ids: map[typeid]ComponentID,
|
|
component_pools: map[typeid]^ComponentPool(any),
|
|
next_component_id: ComponentID,
|
|
|
|
component_pool_destroy_entity_cbs: map[typeid]proc(pool: ^ComponentPool(any), entity_id: EntityID),
|
|
component_pool_delete_cbs: map[typeid]proc(pool: ^ComponentPool(any)),
|
|
}
|
|
|
|
component_manager_init :: proc(component_manager: ^ComponentManager) {
|
|
component_manager.component_ids = make(map[typeid]ComponentID, context.allocator)
|
|
component_manager.component_pools = make(map[typeid]^ComponentPool(any), context.allocator)
|
|
|
|
component_manager.component_pool_destroy_entity_cbs = make(map[typeid]proc(pool: ^ComponentPool(any), entity_id: EntityID), context.allocator)
|
|
component_manager.component_pool_delete_cbs = make(map[typeid]proc(pool: ^ComponentPool(any)), context.allocator)
|
|
|
|
component_manager.next_component_id = 0
|
|
}
|
|
|
|
component_manager_register_component :: proc($Component: typeid, component_manager: ^ComponentManager) {
|
|
log.assertf(Component not_in component_manager.component_ids, "Registering component more than once")
|
|
|
|
component_manager.component_ids[Component] = component_manager.next_component_id
|
|
|
|
component_pool := new(ComponentPool(Component), context.allocator)
|
|
component_pool_init(component_pool)
|
|
|
|
component_manager.component_pools[Component] = cast(^ComponentPool(any))component_pool
|
|
|
|
component_manager.component_pool_destroy_entity_cbs[Component] = proc(any_component_pool: ^ComponentPool(any), entity_id: EntityID) {
|
|
typed_component_pool := cast(^ComponentPool(Component))any_component_pool
|
|
if entity_id in typed_component_pool.entity_to_index {
|
|
component_pool_remove_data(typed_component_pool, entity_id)
|
|
}
|
|
}
|
|
|
|
component_manager.component_pool_delete_cbs[Component] = proc(any_component_pool: ^ComponentPool(any)) {
|
|
typed_component_pool := cast(^ComponentPool(Component))any_component_pool
|
|
component_pool_delete(typed_component_pool)
|
|
free(typed_component_pool)
|
|
}
|
|
|
|
component_manager.next_component_id += 1
|
|
}
|
|
|
|
component_manager_get_component_id :: proc(component_manager: ^ComponentManager, $Component: typeid) -> ComponentID {
|
|
log.assertf(Component in component_manager.component_ids, "Component not registered before use")
|
|
return component_manager.component_ids[Component]
|
|
}
|
|
|
|
component_manager_add_component :: proc(component_manager: ^ComponentManager, component: $Component, entity_id: EntityID) {
|
|
component_pool := cast(^ComponentPool(Component))component_manager.component_pools[Component]
|
|
component_pool_insert_data(component_pool, entity_id, component)
|
|
}
|
|
|
|
component_manager_remove_component :: proc(component_manager: ^ComponentManager, $Component: typeid, entity_id: EntityID) {
|
|
component_pool := cast(^ComponentPool(Component))component_manager.component_pools[Component]
|
|
component_pool_remove_data(component_pool, entity_id)
|
|
}
|
|
|
|
component_manager_get_component :: proc(component_manager: ^ComponentManager, $Component: typeid, entity_id: EntityID) -> ^Component {
|
|
component_pool := cast(^ComponentPool(Component)) component_manager.component_pools[Component]
|
|
return component_pool_get(component_pool, entity_id)
|
|
}
|
|
|
|
component_manager_destroy_entity :: proc(component_manager: ^ComponentManager, entity_id: EntityID) {
|
|
for Component, component_pool in component_manager.component_pools {
|
|
component_manager.component_pool_destroy_entity_cbs[Component](component_pool, entity_id)
|
|
}
|
|
}
|
|
|
|
component_manager_delete :: proc(component_manager: ^ComponentManager) {
|
|
for Component, &component_pool in component_manager.component_pools {
|
|
component_manager.component_pool_delete_cbs[Component](component_pool)
|
|
}
|
|
|
|
delete(component_manager.component_pools)
|
|
delete(component_manager.component_ids)
|
|
|
|
delete(component_manager.component_pool_destroy_entity_cbs)
|
|
delete(component_manager.component_pool_delete_cbs)
|
|
}
|
|
|