lib/felflame/system_manager.rb in felflame-3.0.0 vs lib/felflame/system_manager.rb in felflame-4.0.0
- old
+ new
@@ -1,23 +1,34 @@
-class FelFlame
+# frozen_string_literal: true
+
+module FelFlame
class Systems
# How early this System should be executed in a list of Systems
attr_accessor :priority
# The Constant name assigned to this System
- attr_reader :const_name
# 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 all the scenes this system is a part of.
+ attr_writer :scenes
+
+ def scenes
+ @scenes ||= []
+ end
+
def priority=(priority)
@priority = priority
- FelFlame::Stage.systems.sort_by!(&:priority)
+ scenes.each do |scene|
+ scene.systems = scene.systems.sort_by(&:priority)
+ end
end
+
# 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 FelFlame automatically.
# @return [Array<Component>]
@@ -32,27 +43,60 @@
# @return [Array<Component>]
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<Symbol>>]
def attr_triggers
@attr_triggers ||= {}
end
- class <<self
- include Enumerable
+ class << self
+ # Stores the systems in {FelFlame::Components}. This
+ # is needed because calling `FelFlame::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
+ def const_cache
+ @const_cache || update_const_cache
+ end
- # Iterate over all Systems, sorted by their priority. You also call other enumerable methods instead of each, such as +each_with_index+ or +select+
- # @return [Enumerator]
- def each(&block)
- constants.map { |sym| const_get(sym) }.sort_by(&:priority).reverse.each(&block)
+ # Updates the array that stores the constants.
+ # Used internally by FelFlame
+ # @!visibility private
+ def update_const_cache
+ @const_cache = constants.map do |constant|
+ const_get constant
+ end
end
+
+ # Forwards undefined methods to the array of constants
+ # if the array can handle the request. Otherwise tells
+ # the programmer their code errored
+ # @!visibility private
+ def respond_to_missing?(method, *)
+ if const_cache.respond_to? method
+ true
+ else
+ super
+ end
+ end
+
+ # Makes system module behave like arrays with additional
+ # methods for managing the array
+ # @!visibility private
+ def method_missing(method, *args, **kwargs, &block)
+ if const_cache.respond_to? method
+ const_cache.send(method, *args, **kwargs, &block)
+ else
+ super
+ end
+ end
end
# Creates a new System which can be accessed as a constant under the namespace {FelFlame::Systems}.
# The name given is what constant the system is assigned to
#
@@ -68,19 +112,21 @@
# @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.
def initialize(name, priority: 0, &block)
FelFlame::Systems.const_set(name, self)
- @const_name = name
+ FelFlame::Systems.update_const_cache
@priority = priority
@block = block
+ @scenes = []
end
# Manually execute the system a single time
def call
@block.call
end
+
# 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.
def redefine(&block)
@block = block
end
@@ -107,71 +153,70 @@
# FelFlame::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+
def clear_triggers(*trigger_types, component_or_manager: nil)
- trigger_types = [:addition_triggers, :removal_triggers, :attr_triggers] if trigger_types.empty?
+ trigger_types = %i[addition_triggers removal_triggers attr_triggers] if trigger_types.empty?
if trigger_types.include? :attr_triggers
- if (trigger_types - [:addition_triggers,
- :removal_triggers,
- :attr_triggers]).empty?
+ if (trigger_types - %i[addition_triggers
+ removal_triggers
+ attr_triggers]).empty?
if component_or_manager.nil?
- #remove all attrs
- self.attr_triggers.each do |cmp_or_mgr, attrs|
+ # 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 self.attr_triggers[component_or_manager].nil?
- self.attr_triggers[component_or_manager].each do |attr|
+ # 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
- self.attr_triggers[component_or_manager] = []
+ attr_triggers[component_or_manager] = []
end
end
- else
+ elsif component_or_manager.nil?
- if component_or_manager.nil?
- (trigger_types - [:addition_triggers, :removal_triggers, :attr_triggers]).each do |attr|
- #remove attr
- self.attr_triggers.each do |cmp_or_mgr, attrs|
- cmp_or_mgr.attr_triggers[attr].delete self
- end
+ (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
- self.attr_triggers.delete (trigger_types - [:addition_triggers,
- :removal_triggers,
- :attr_triggers])
- else
- #remove attr from component_or_manager
- (trigger_types - [: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
- self.attr_triggers[component_or_manager] -= trigger_types unless self.attr_triggers[component_or_manager].nil?
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 & [:removal_triggers, :addition_triggers] - [:attr_triggers]).each do |trigger_type|
+ (trigger_types & %i[removal_triggers addition_triggers] - [:attr_triggers]).each do |trigger_type|
if component_or_manager.nil?
- #remove all removal triggers
- self.send(trigger_type).each do |trigger|
+ # remove all removal triggers
+ send(trigger_type).each do |trigger|
trigger.send(trigger_type).delete self
end
- self.send("#{trigger_type.to_s}=", [])
+ send("#{trigger_type}=", [])
else
- #remove removal trigger relevant to comp/man
- self.send(trigger_type).delete component_or_manager
+ # 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
@@ -200,13 +245,13 @@
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 self.attr_triggers[component_or_manager].nil?
- self.attr_triggers[component_or_manager] = [attr]
+ if attr_triggers[component_or_manager].nil?
+ attr_triggers[component_or_manager] = [attr]
else
- self.attr_triggers[component_or_manager] |= [attr]
+ attr_triggers[component_or_manager] |= [attr]
end
true
end
end
end