class Baku::EntityManager

The EntityManager stores entities in such a way that they can be retrieved efficiently by either ComponentMask or tag. Before storing any entities, the ComponentMasks that we wish to match on should be registered. This step is performed transparently by the World whenever a System is added.

Public Class Methods

new() click to toggle source
# File lib/baku/entity_manager.rb, line 7
def initialize
  @entities_by_component_mask = {}
  @entities_by_tag = {}
end

Public Instance Methods

add_entity(entity) click to toggle source
# File lib/baku/entity_manager.rb, line 21
def add_entity(entity)
  add_entity_to_matching_component_lists(entity)
  
  entity.add_event_listener(
    :component_added,
    method(:on_entity_component_added)
  )
  entity.add_event_listener(
    :component_removed,
    method(:on_entity_component_removed)
  )

  entity.tags.each do |tag|
    @entities_by_tag[tag] ||= []
    @entities_by_tag[tag] << entity
  end
end
dispose() click to toggle source
# File lib/baku/entity_manager.rb, line 12
def dispose
  @entities_by_component_mask.clear
  @entities_by_tag.clear
end
get_entities(component_mask) click to toggle source
# File lib/baku/entity_manager.rb, line 60
def get_entities(component_mask)
  @entities_by_component_mask[component_mask] || []
end
get_entities_by_tag(tag) click to toggle source
# File lib/baku/entity_manager.rb, line 64
def get_entities_by_tag(tag)
  @entities_by_tag[tag] || []
end
register_component_mask(component_mask) click to toggle source
# File lib/baku/entity_manager.rb, line 17
def register_component_mask(component_mask)
  @entities_by_component_mask[component_mask] = []
end
remove_entity(entity) click to toggle source
# File lib/baku/entity_manager.rb, line 39
def remove_entity(entity)
  entity.tags.each do |tag|
    @entities_by_tag[tag].delete(entity)
  end
  
  entity.remove_event_listener(
    :component_added,
    method(:on_entity_component_added)
  )
  entity.remove_event_listener(
    :component_removed,
    method(:on_entity_component_removed)
  )

  @entities_by_component_mask.each do |component_mask, entities|
    if component_mask.matches?(entity.component_mask)
      entities.delete(entity)
    end
  end
end

Private Instance Methods

add_entity_to_matching_component_lists(entity) click to toggle source
# File lib/baku/entity_manager.rb, line 70
def add_entity_to_matching_component_lists(entity)
  @entities_by_component_mask.each do |component_mask, entities|
    component_mask_match = component_mask.matches?(entity.component_mask)

    if component_mask_match && !entities.include?(entity)
      entities << entity
    end
  end
end
on_entity_component_added(entity, component) click to toggle source
# File lib/baku/entity_manager.rb, line 80
def on_entity_component_added(entity, component)
  add_entity_to_matching_component_lists(entity)
end
on_entity_component_removed(entity, component) click to toggle source
# File lib/baku/entity_manager.rb, line 84
def on_entity_component_removed(entity, component)
  old_mask = ComponentMask.from_components(entity.components.keys + [component.class])
  new_mask = entity.component_mask

  @entities_by_component_mask.each do |component_mask, entities|
    old_match = component_mask.matches?(old_mask)
    new_match = component_mask.matches?(new_mask)
    
    if old_match && !new_match
      entities.delete(entity)
    end
  end      
end