class FelFlame class Components @component_map = [] class <] def addition_triggers @addition_triggers ||= [] end # Stores references to systems that should be triggered when a # component from this manager is removed. # Do not edit this array as it is managed by FelFlame automatically. # @return [Array] def removal_triggers @removal_triggers ||= [] end # Stores references to systems that should be triggered when an # attribute from this manager is changed. # Do not edit this hash as it is managed by FelFlame automatically. # @return [Hash>] def attr_triggers @attr_triggers ||= {} end # Creates a new component and sets the values of the attributes given to it. If an attritbute is not passed then it will remain as the default. # @param attrs [Keyword: Value] You can pass any number of Keyword-Value pairs # @return [Component] def initialize(**attrs) # Prepare the object # (this is a function created with metaprogramming # in FelFlame::Components set_defaults # Generate ID new_id = self.class.data.find_index { |i| i.nil? } new_id = self.class.data.size if new_id.nil? @id = new_id # Fill params attrs.each do |key, value| send "#{key}=", value end # Save Component self.class.data[new_id] = self end class <] def addition_triggers @addition_triggers ||= [] end # Stores references to systems that should be triggered when this # component is removed from an enitity. # Do not edit this array as it is managed by FelFlame automatically. # @return [Array] def removal_triggers @removal_triggers ||= [] end # Stores references to systems that should be triggered when an # attribute from this component changed. # Do not edit this hash as it is managed by FelFlame automatically. # @return [Hash] def attr_triggers @attr_triggers ||= {} end # @return [Array] Array of all Components that belong to a given component manager # @!visibility private def data @data ||= [] end # Gets a Component from the given {id unique ID}. Usage is simular to how an Array lookup works. # # @example # # this gets the 'Health' Component with ID 7 # FelFlame::Components::Health[7] # @param component_id [Integer] # @return [Component] Returns the Component that uses the given unique {id ID}, nil if there is no Component associated with the given {id ID} def [](component_id) data[component_id] end # Iterates over all components within the component manager. # Special Enumerable methods like +map+ or +each_with_index+ are not implemented # @return [Enumerator] def each(&block) data.compact.each(&block) end end # An alias for the {id ID Reader} # @return [Integer] def to_i id end # A list of entity ids that are linked to the component # @return [Array] def entities @entities ||= [] end # Update attribute values using a hash or keywords. # @return [Hash] Hash of updated attributes def update_attrs(**opts) opts.each do |key, value| send "#{key}=", value end end # Execute systems that have been added to execute on variable change # @return [Boolean] +true+ def attr_changed_trigger_systems(attr) systems_to_execute = self.class.attr_triggers[attr] systems_to_execute = [] if systems_to_execute.nil? systems_to_execute |= attr_triggers[attr] unless attr_triggers[attr].nil? systems_to_execute.sort_by(&:priority).reverse.each(&:call) true end # Removes this component from the list and purges all references to this Component from other Entities, as well as its {id ID} and data. # @return [Boolean] +true+. def delete addition_triggers.each do |system| system.clear_triggers component_or_manager: self end # This needs to be cloned because indices get deleted as # the remove command is called, breaking the loop if it # wasn't referencing a clone(will get Nil errors) iter = entities.map(&:clone) iter.each do |entity| #FelFlame::Entities[entity_id].remove self #unless FelFlame::Entities[entity_id].nil? entity.remove self end self.class.data[id] = nil instance_variables.each do |var| instance_variable_set(var, nil) end true end # @return [Hash] A hash, where all the keys are attributes linked to their respective values. def attrs return_hash = instance_variables.each_with_object({}) do |key, final| final[key.to_s.delete_prefix('@').to_sym] = instance_variable_get(key) end return_hash.delete(:attr_triggers) return_hash end # Export all data into a JSON String, which could then later be loaded or saved to a file # TODO: This function is not yet complete # @return [String] a JSON formatted String #def to_json # # should return a json or hash of all data in this component #end end end