class FelECS::Systems

Creates and manages Systems. Systems are the logic of the game and do not contain any data within them. Any systems you create are accessable under the {FelECS::Systems} namespace as Constants. You can use array methods directly on this class to access Systems.

Attributes

addition_triggers[W]

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_triggers[W]

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

priority[RW]

How early this System should be executed in a list of Systems

removal_triggers[W]

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

scenes[W]

Stores all the scenes this system is a part of.

Public Class Methods

const_cache() click to toggle source

Stores the systems in {FelECS::Components}. This is needed because calling ‘FelECS::Components.constants` will not let you iterate over the value of the constants but will instead give you an array of symbols. This caches the convertion of those symbols to the actual value of the constants

# File lib/felecs/system_manager.rb, line 63
def const_cache
  @const_cache || update_const_cache
end
method_missing(method, *args, **kwargs, &block) click to toggle source

Makes system module behave like arrays with additional methods for managing the array @!visibility private

Calls superclass method
# File lib/felecs/system_manager.rb, line 91
def method_missing(method, *args, **kwargs, &block)
  if const_cache.respond_to? method
    const_cache.send(method, *args, **kwargs, &block)
  else
    super
  end
end
new(name, priority: 0, &block) click to toggle source

Creates a new System which can be accessed as a constant under the namespace {FelECS::Systems}. The name given is what constant the system is assigned to

@example

FelECS::Systems.new('PassiveHeal', priority: -2) do
  FelECS::Components::Health.each do |component|
    component.hp += 5
  end
end
# Give it a low priority so other systems such as a
#   Poison system would kill the player first

@param name [String] The name this system will use. Needs to to be in the Ruby Constant format. @param priority [Integer] Which priority order this system should be executed in relative to other systems. Higher means executed earlier. @param block [Proc] The code you wish to be executed when the system is triggered. Can be defined by using a +do end+ block or using +{ }+ braces.

# File lib/felecs/system_manager.rb, line 115
def initialize(name, priority: 0, &block)
  FelECS::Systems.const_set(name, self)
  FelECS::Systems.update_const_cache
  @priority = priority
  @block = block
  @scenes = []
end
respond_to_missing?(method, *) click to toggle source

Forwards undefined methods to the array of constants if the array can handle the request. Otherwise tells the programmer their code errored @!visibility private

Calls superclass method
# File lib/felecs/system_manager.rb, line 80
def respond_to_missing?(method, *)
  if const_cache.respond_to? method
    true
  else
    super
  end
end
update_const_cache() click to toggle source

Updates the array that stores the constants. Used internally by FelECS @!visibility private

# File lib/felecs/system_manager.rb, line 70
def update_const_cache
  @const_cache = constants.map do |constant|
    const_get constant
  end
end

Public Instance Methods

addition_triggers() click to toggle source

Stores references to components or their managers that trigger this component when a component or component from that manager is added to an entity. Do not edit this hash as it is managed by FelECS automatically. @return [Array<Component>]

# File lib/felecs/system_manager.rb, line 35
def addition_triggers
  @addition_triggers ||= []
end
attr_triggers() click to toggle source

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 FelECS automatically. @return [Hash<Symbol, Array<Symbol>>]

# File lib/felecs/system_manager.rb, line 52
def attr_triggers
  @attr_triggers ||= {}
end
call() click to toggle source

Manually execute the system a single time

# File lib/felecs/system_manager.rb, line 124
def call
  @block.call
end
clear_triggers(*trigger_types, component_or_manager: nil) click to toggle source

Removes triggers from this system. This function is fairly flexible so it can accept a few different inputs For addition and removal triggers, you can optionally pass in a component, or a manager to clear specifically the relevant triggers for that one component or manager. If you do not pass a component or manager then it will clear triggers for all components and managers. For attr_triggers @example

# To clear all triggers that execute this system when a component is added:
FelECS::Systems::ExampleSystem.clear_triggers :addition_triggers
# Same as above but for when a component is removed instead
FelECS::Systems::ExampleSystem.clear_triggers :removal_triggers
# Same as above but for when a component has a certain attribute changed
FelECS::Systems::ExampleSystem.clear_triggers :attr_triggers

# Clear a trigger from a specific component
FelECS::Systems::ExampleSystem.clear_triggers :addition_triggers, FelECS::Component::ExampleComponent[0]
# Clear a trigger from a specific component manager
FelECS::Systems::ExampleSystem.clear_triggers :addition_triggers, FelECS::Component::ExampleComponent

# Clear the trigger that executes a system when the ':example_attr' is changes
FelECS::Systems::ExampleSystem.clear_triggers :attr_triggers, :example_attr

@param trigger_types [:Symbols] One or more of the following trigger types: :addition_triggers, :removal_triggers, or :attr_triggers. If attr_triggers is used then you may pass attributes you wish to be cleared as symbols in this parameter as well @param component_or_manager [Component or ComponentManager] The object to clear triggers from. Use Nil to clear triggers from all components associated with this system. @return [Boolean] true

# File lib/felecs/system_manager.rb, line 157
def clear_triggers(*trigger_types, component_or_manager: nil)
  trigger_types = %i[addition_triggers removal_triggers attr_triggers] if trigger_types.empty?

  if trigger_types.include? :attr_triggers
    if (trigger_types - %i[addition_triggers
        removal_triggers
        attr_triggers]).empty?

        if component_or_manager.nil?
          # remove all attrs
          attr_triggers.each do |cmp_or_mgr, attrs|
            attrs.each do |attr|
              next if cmp_or_mgr.attr_triggers[attr].nil?

              cmp_or_mgr.attr_triggers[attr].delete self
            end
            self.attr_triggers = {}
          end
        else
          # remove attrs relevant to comp_or_man
          unless attr_triggers[component_or_manager].nil?
            attr_triggers[component_or_manager].each do |attr|
              component_or_manager.attr_triggers[attr].delete self
            end
            attr_triggers[component_or_manager] = []
          end
        end

    elsif component_or_manager.nil?

      (trigger_types - %i[addition_triggers removal_triggers attr_triggers]).each do |attr|
        # remove attr
        attr_triggers.each do |cmp_or_mgr, _attrs|
          cmp_or_mgr.attr_triggers[attr].delete self
        end
      end
      attr_triggers.delete(trigger_types - %i[addition_triggers
                           removal_triggers
                           attr_triggers])
    else
      # remove attr from component_or_manager
      (trigger_types - %i[addition_triggers removal_triggers attr_triggers]).each do |attr|
        next if component_or_manager.attr_triggers[attr].nil?

        component_or_manager.attr_triggers[attr].delete self
      end
      attr_triggers[component_or_manager] -= trigger_types unless attr_triggers[component_or_manager].nil?

    end
  end

  (trigger_types & %i[removal_triggers addition_triggers] - [:attr_triggers]).each do |trigger_type|
    if component_or_manager.nil?
      # remove all removal triggers
      send(trigger_type).each do |trigger|
        trigger.send(trigger_type).delete self
      end
      send("#{trigger_type}=", [])
    else
      # remove removal trigger relevant to comp/man
      send(trigger_type).delete component_or_manager
      component_or_manager.send(trigger_type).delete self
    end
  end
  true
end
priority=(priority) click to toggle source
# File lib/felecs/system_manager.rb, line 23
def priority=(priority)
  @priority = priority
  scenes.each do |scene|
    scene.systems = scene.systems.sort_by(&:priority)
  end
end
redefine(&block) click to toggle source

Redefine what code is executed by this System when it is called upon. @param block [Proc] The code you wish to be executed when the system is triggered. Can be defined by using a +do end+ block or using +{ }+ braces.

# File lib/felecs/system_manager.rb, line 130
def redefine(&block)
  @block = block
end
removal_triggers() click to toggle source

Stores references to components or their managers that trigger this component when a component or component from that manager is removed from an entity. Do not edit this hash as it is managed by FelECS automatically. @return [Array<Component>]

# File lib/felecs/system_manager.rb, line 44
def removal_triggers
  @removal_triggers ||= []
end
scenes() click to toggle source
# File lib/felecs/system_manager.rb, line 19
def scenes
  @scenes ||= []
end
trigger_when_added(component_or_manager) click to toggle source

Add a component or component manager so that it triggers this system when the component or a component from the component manager is added to an entity @param component_or_manager [Component or ComponentManager] The component or component manager to trigger this system when added @return [Boolean] true

# File lib/felecs/system_manager.rb, line 227
def trigger_when_added(component_or_manager)
  self.addition_triggers |= [component_or_manager]
  component_or_manager.addition_triggers |= [self]
  true
end
trigger_when_is_changed(component_or_manager, attr) click to toggle source

Add a component or component manager so that it triggers this system when a component’s attribute is changed. @return [Boolean] true

# File lib/felecs/system_manager.rb, line 244
def trigger_when_is_changed(component_or_manager, attr)
  if component_or_manager.attr_triggers[attr].nil?
    component_or_manager.attr_triggers[attr] = [self]
  else
    component_or_manager.attr_triggers[attr] |= [self]
  end
  if attr_triggers[component_or_manager].nil?
    attr_triggers[component_or_manager] = [attr]
  else
    attr_triggers[component_or_manager] |= [attr]
  end
  true
end
trigger_when_removed(component_or_manager) click to toggle source

Add a component or component manager so that it triggers this system when the component or a component from the component manager is removed from an entity @param component_or_manager [Component or ComponentManager] The component or component manager to trigger this system when removed @return [Boolean] true

# File lib/felecs/system_manager.rb, line 236
def trigger_when_removed(component_or_manager)
  self.removal_triggers |= [component_or_manager]
  component_or_manager.removal_triggers |= [self]
  true
end