#+private package ecs import "base:intrinsics" import "core:log" @(private = "file") EntitySet :: map[EntityID]struct{} SystemBase :: struct { entities: EntitySet } SystemManager :: struct { signatures: map[typeid]Signature, systems: map[typeid]^SystemBase } system_base_init :: proc(system_base: ^SystemBase) { system_base.entities = make(EntitySet, context.allocator) } system_manager_init :: proc(system_manager: ^SystemManager) { system_manager.signatures = make(map[typeid]Signature, context.allocator) system_manager.systems = make(map[typeid]^SystemBase, context.allocator) } system_manager_register_system :: proc(system_manager: ^SystemManager, $System: typeid) -> ^System { log.assertf(System not_in system_manager.systems, "Registering system more than once") log.assertf(intrinsics.type_has_field(System, "entities"), "Registering non system type") system := new(System, context.allocator) system_base_init(system) system_manager.systems[System] = system return system } system_manager_set_signature :: proc(system_manager: ^SystemManager, $System: typeid, signature: Signature) { log.assertf(System in system_manager.systems, "System used before registered") system_manager.signatures[System] = signature } system_manager_destroy_entity :: proc(system_manager: ^SystemManager, entity_id: EntityID) { for _, system in system_manager.systems { delete_key(&system.entities, entity_id) } } system_manager_change_entity_signature :: proc(system_manager: ^SystemManager, entity_id: EntityID, entity_signature: Signature) { for type, system in system_manager.systems { system_signature := system_manager.signatures[type] if (entity_signature & system_signature) == system_signature { system.entities[entity_id] = {} } else { delete_key(&system.entities, entity_id) } } } system_manager_delete :: proc(system_manager: ^SystemManager) { for _, system in system_manager.systems { delete(system.entities) free(system) } delete(system_manager.systems) delete(system_manager.signatures) }