diff options
Diffstat (limited to 'component_manager.rb')
| -rw-r--r-- | component_manager.rb | 312 |
1 files changed, 155 insertions, 157 deletions
diff --git a/component_manager.rb b/component_manager.rb index c81f645..3ffdff3 100644 --- a/component_manager.rb +++ b/component_manager.rb @@ -7,7 +7,7 @@ class FelFlame @component_map = [] class <<self include Enumerable - # Creates a new {FelFlame::Helper::ComponentManager component manager}. + # Creates a new {FelFlame::ComponentManager component manager}. # # @example # # Here color is set to default to red @@ -25,12 +25,13 @@ class FelFlame raise(NameError.new, "Component Manager '#{component_name}' is already defined") end - const_set(component_name, Class.new(FelFlame::Helper::ComponentManager) {}) + + const_set(component_name, Class.new(FelFlame::ComponentManager) {}) attrs.each do |attr| FelFlame::Components.const_get(component_name).attr_accessor attr end attrs_with_defaults.each do |attr, _default| - #FelFlame::Components.const_get(component_name).attr_accessor attr + attrs_with_defaults[attr] = _default.dup FelFlame::Components.const_get(component_name).attr_reader attr FelFlame::Components.const_get(component_name).define_method("#{attr}=") do |value| attr_changed_trigger_systems(attr) unless value.equal? send(attr) @@ -39,7 +40,7 @@ class FelFlame end FelFlame::Components.const_get(component_name).define_method(:set_defaults) do attrs_with_defaults.each do |attr, default| - instance_variable_set("@#{attr}", default) + instance_variable_set("@#{attr}", default.dup) end end FelFlame::Components.const_get(component_name) @@ -52,21 +53,75 @@ class FelFlame end end end - # Namespace for helper functions and template classes - class Helper - # Component Managers are what is used to create individual components which can be attached to entities. - # When a Component is created from a Component Manager that has accessors given to it, you can set or get the values of those accessors using standard ruby message sending (e.g [email protected] = 5+), or by using the {#attrs} and {#update_attrs} methods instead. - class ComponentManager - - # Holds the {id unique ID} of a component. The {id ID} is only unique within the scope of the component manager it was created from. - # @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 + + # Component Managers are what is used to create individual components which can be attached to entities. + # When a Component is created from a Component Manager that has accessors given to it, you can set or get the values of those accessors using standard ruby message sending (e.g [email protected] = 5+), or by using the {#attrs} and {#update_attrs} methods instead. + class ComponentManager + + # Holds the {id unique ID} of a component. The {id ID} is only unique within the scope of the component manager it was created from. + # @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 + + # Allows overwriting the storage of triggers, such as for clearing. + # This method should generally only need to be used internally and + # not by a game developer. + # @!visibility private + attr_writer :addition_triggers, :removal_triggers, :attr_triggers + + # Stores references to systems that should be triggered when a + # component from this manager is added. + # Do not edit this array as it is managed by FelFlame automatically. + # @return [Array<System>] + 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<System>] + 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<Symbol, Array<System>>] + 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 <<self # Allows overwriting the storage of triggers, such as for clearing. # This method should generally only need to be used internally and @@ -74,16 +129,16 @@ class FelFlame # @!visibility private attr_writer :addition_triggers, :removal_triggers, :attr_triggers - # Stores references to systems that should be triggered when a - # component from this manager is added. + # Stores references to systems that should be triggered when this + # component is added to an enitity. # Do not edit this array as it is managed by FelFlame automatically. # @return [Array<System>] def addition_triggers @addition_triggers ||= [] end - # Stores references to systems that should be triggered when a - # component from this manager is removed. + # 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<System>] def removal_triggers @@ -91,161 +146,104 @@ class FelFlame end # Stores references to systems that should be triggered when an - # attribute from this manager is changed. + # attribute from this component changed. # Do not edit this hash as it is managed by FelFlame automatically. - # @return [Hash<Symbol, Array<System>>] + # @return [Hash<Symbol, System>] 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 + # @return [Array<Component>] Array of all Components that belong to a given component manager + # @!visibility private + def data + @data ||= [] end - class <<self - - # Allows overwriting the storage of triggers, such as for clearing. - # This method should generally only need to be used internally and - # not by a game developer. - # @!visibility private - attr_writer :addition_triggers, :removal_triggers, :attr_triggers - - # Stores references to systems that should be triggered when this - # component is added to an enitity. - # Do not edit this array as it is managed by FelFlame automatically. - # @return [Array<System>] - 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<System>] - 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<Symbol, System>] - def attr_triggers - @attr_triggers ||= {} - end - - # @return [Array<Component>] 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 + # 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 - # An alias for the {id ID Reader} - # @return [Integer] - def to_i - id + # 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 - # A list of entity ids that are linked to the component - # @return [Array<Integer>] - def entities - @entities ||= [] - end + # An alias for the {id ID Reader} + # @return [Integer] + def to_i + id + end - # Update attribute values using a hash or keywords. - # @return Hash of updated attributes - def update_attrs(**opts) - opts.each do |key, value| - send "#{key}=", value - end + # A list of entity ids that are linked to the component + # @return [Array<Integer>] + def entities + @entities ||= [] + end + + # Update attribute values using a hash or keywords. + # @return [Hash<Symbol, Value>] 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 - def attr_changed_trigger_systems(attr) - systems_to_execute = self.class.attr_triggers[attr] - systems_to_execute = [] if systems_to_execute.nil? + # 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 |= attr_triggers[attr] unless attr_triggers[attr].nil? - systems_to_execute.sort_by(&:priority).reverse.each(&:call) - #self.attr_triggers.each do |system| - # systems_to_execute |= [system] - #end - end + 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_id| - FelFlame::Entities[entity_id].remove self #unless FelFlame::Entities[entity_id].nil? - end - self.class.data[id] = nil - instance_variables.each do |var| - instance_variable_set(var, nil) - end - true + # 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 - - # @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 + # 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_id| + FelFlame::Entities[entity_id].remove self #unless FelFlame::Entities[entity_id].nil? end + self.class.data[id] = nil + instance_variables.each do |var| + instance_variable_set(var, nil) + end + true + 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 + # @return [Hash<Symbol, Value>] 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 |
