EntityCoolSystem/src/ecs/entity_container.cr

60 lines
1.7 KiB
Crystal

module ECS::EntityContainer
@entities = Array(ECS::Entity).new
include ECS::World::HasWorldRef
def <<(entity : ECS::Entity)
@entities << entity
self
end
def generate_entity : ECS::Entity
entity = ECS::Entity.random
self << entity
entity
end
def components_of(entity : ECS::Entity) : Array(ECS::Component)
world.components.map do |comp_type, comp_list|
comp_list.select { |component| component.entity == entity }
end.flatten
end
def component_of?(entity : ECS::Entity, comp_type : ECS::Component.class) : ECS::Component?
component = world.components[comp_type].find do |comp|
comp.entity == entity
end
component
end
def component_of(entity : ECS::Entity, comp_type : ECS::Component.class) : ECS::Component
component = component_of?(entity, comp_type)
raise "Component not found #{comp_type} for #{entity} in #{self.class}" if component.nil?
component
end
def every(*comp_types : ECS::Component.class) : Array(ECS::Entity)
comp_types.map do |comp_type|
world[comp_type]? || Array(ECS::Component).new
end.reduce do |left_comp_list, right_comp_list|
left_comp_list & right_comp_list
end.map do |comp|
comp.entity
end
end
def any(*comp_types : ECS::Component.class) : Array(ECS::Entity)
comp_types.map do |comp_type|
world[comp_type]? || Array(ECS::Component).new
end.reduce do |left_comp_list, right_comp_list|
left_comp_list | right_comp_list
end
end
def none(*comp_types : ECS::Component.class) : Array(ECS::Entity)
reversed_comp_types = components.keys.select do |comp_type|
!comp_types.includes? comp_type
end
every(reversed_comp_types)
end
end