diff options
Diffstat (limited to 'lib/felflame/entity_manager.rb')
| -rw-r--r-- | lib/felflame/entity_manager.rb | 99 |
1 files changed, 43 insertions, 56 deletions
diff --git a/lib/felflame/entity_manager.rb b/lib/felflame/entity_manager.rb index 9489f29..a05ef93 100644 --- a/lib/felflame/entity_manager.rb +++ b/lib/felflame/entity_manager.rb @@ -1,59 +1,53 @@ -module FelFlame +class FelFlame class Entities + # Holds the unique ID of this entity + # @return [Integer] + attr_reader :id + + # A seperate attr_writer was made for documentation readability reasons. + # Yard will list attr_reader is readonly which is my intention. + # This value needs to be changable as it is set by other functions. + # @!visibility private + attr_writer :id # Creating a new Entity # @param components [Components] Can be any number of components, identical duplicates will be automatically purged however different components from the same component manager are allowed. # @return [Entity] def initialize(*components) + # Assign new unique ID + new_id = self.class.data.find_index(&:nil?) + new_id = self.class.data.size if new_id.nil? + self.id = new_id + # Add each component add(*components) - # Fancy method redirection for when the `component` method is called - @component_redirect = Object.new - @component_redirect.instance_variable_set(:@entity, self) - @component_redirect.define_singleton_method(:[]) do |component_manager| - instance_variable_get(:@entity).component(component_manager) - end - - self.class._data.push self + self.class.data[id] = self end - # A hash that uses component manager constant names as keys, and where the values of those keys are arrays that contain the the components attached to this entity. + # A hash that uses component manager constant names as keys, and where the values of those keys are arrays that contain the {FelFlame::ComponentManager#id IDs} of the components attached to this entity. # @return [Hash<Component_Manager, Array<Integer>>] def components @components ||= {} end - # A single component from a component manager. Use this if you expect the component to only belong to one entity and you want to access it. Access the component using either parameter notation or array notation. - # @example - # @entity.component[@component_manager] # array notation - # @entity.component(@component_manager) # method notation - # @param manager [ComponentManager] If you pass nil you can then use array notation to access the same value. - # @return [Component] - def component(manager = nil) - if manager.nil? - @component_redirect - else - if components[manager].nil? - raise "This entity(#{self}) doesnt have any components of this type: #{manager}" - elsif components[manager].length > 1 - Warning.warn("This entity has MANY of this component but you called the method that is intended for having a single of this component type.\nYou may have a bug in your logic.") - end - components[manager].first - end + # An alias for the {#id ID reader} + # @return [Integer] + def to_i + id end - - # Removes this Entity from the list and purges all references to this Entity from other Components, as well as its data. + # Removes this Entity from the list and purges all references to this Entity from other Components, as well as its {id ID} and data. # @return [Boolean] +true+ def delete components.each do |component_manager, component_array| - component_array.reverse_each do |component| + component_array.each do |component| component.entities.delete(self) end end - FelFlame::Entities._data.delete self + FelFlame::Entities.data[id] = nil @components = {} + @id = nil true end @@ -95,9 +89,6 @@ module FelFlame check_systems component, :removal_triggers if component.entities.include? self component.entities.delete self components[component.class].delete component - if components[component.class].empty? - components.delete component.class - end end true end @@ -108,33 +99,29 @@ module FelFlame #def to_json() end class <<self - # Makes component managers behave like arrays with additional - # methods for managing the array + include Enumerable + # @return [Array<Entity>] Array of all Entities that exist # @!visibility private - def respond_to_missing?(method, *) - if self._data.respond_to? method - true - else - super - end + def data + @data ||= [] end - # Makes component managers behave like arrays with additional - # methods for managing the array - # @!visibility private - def method_missing(method, *args, **kwargs, &block) - if self._data.respond_to? method - self._data.send(method, *args, **kwargs, &block) - else - super - end + # Gets an Entity from the given {id unique ID}. Usage is simular to how an Array lookup works + # + # @example + # # This gets the Entity with ID 7 + # FelFlame::Entities[7] + # @param entity_id [Integer] + # @return [Entity] returns the Entity that uses the given unique ID, nil if there is no Entity associated with the given ID + def [](entity_id) + data[entity_id] end - - # @return [Array<Entity>] Array of all Entities that exist - # @!visibility private - def _data - @data ||= [] + # Iterates over all entities. The data is compacted so that means index does not correlate to ID. + # You also call other enumerable methods instead of each, such as +each_with_index+ or +select+ + # @return [Enumerator] + def each(&block) + data.compact.each(&block) end # Creates a new entity using the data from a JSON string |
