An expression of component-matching criteria used to find entities that should be processed by a System.
- all_of R
The Set of component types which matching entities must have all of.
- none_of R
The Set of component types which matching entities must not have any of.
- one_of R
The Set of component types which matching entities must have at least one of.
for_archetype( archetype )
Create a new Aspect that will match the given archetype, unless the given archetype was created from an existing Aspect, in which case just returns that.
44 def self::for_archetype( archetype )
45 return archetype.from_aspect if archetype.from_aspect
46 return self.new.with_all_of( archetype.components.keys )
47 end
new( one_of: [], all_of: [], none_of: [] )
Create a new empty Aspect
51 def initialize( one_of: [], all_of: [], none_of: [] )
52 @one_of = Set.new( one_of )
53 @all_of = Set.new( all_of )
54 @none_of = Set.new( none_of )
55 end
with_all_of( *component_types )
Return a new Aspect that will match entities with all of the specified component_types.
29 def self::with_all_of( *component_types )
30 return self.new( all_of: component_types.flatten )
31 end
with_none_of( *component_types )
Return a new Aspect that will match entities with none of the specified component_types.
36 def self::with_none_of( *component_types )
37 return self.new( none_of: component_types.flatten )
38 end
with_one_of( *component_types )
Return a new Aspect that will match entities with at least one of the specified component_types.
22 def self::with_one_of( *component_types )
23 return self.new( one_of: component_types.flatten )
24 end
and_all_of( *component_types )
and_none_of( *component_types )
and_one_of( *component_types )
Return an (anonymous) Chione::Archetype module that can be used to create entities that match it.
147 def archetype
148 return Chione::Archetype.from_aspect( self )
149 end
Returns true if the receiver is an empty aspect, i.e., matches all entities.
106 def empty?
107 return self.one_of.empty? && self.all_of.empty? && self.none_of.empty?
108 end
Copy constructor.
59 def initialize_copy( other )
60 super
61 @one_of = @one_of.dup
62 @all_of = @all_of.dup
63 @none_of = @none_of.dup
64 end
matches?( component_hash )
Returns true if the components contained in the specified component_hash match the Aspect’s specifications.
113 def matches?( component_hash )
114 return true if self.empty?
115
116 component_hash = component_hash.components if component_hash.respond_to?( :components )
117
118 return false unless self.one_of.empty? ||
119 self.one_of.any? {|component| component_hash.key?(component) }
120 return false unless self.none_of.none? {|component| component_hash.key?(component) }
121 return false unless self.all_of.all? {|component| component_hash.key?(component) }
122
123 return true
124 end
matching_entities( entity_hash )
Given an entity_hash keyed by Component class, return the subset of values matching the receiving Aspect.
130 def matching_entities( entity_hash )
131 initial_set = if self.one_of.empty?
132 entity_hash.values
133 else
134 entity_hash.values_at( *self.one_of )
135 end
136
137 with_one = initial_set.reduce( :| ) || Set.new
138 with_all = entity_hash.values_at( *self.all_of ).reduce( with_one, :& )
139 without_any = entity_hash.values_at( *self.none_of ).reduce( with_all, :- )
140
141 return without_any
142 end
with_all_of( *component_types )
Return a dup of this Aspect that also requires that matching entities have all of the given component_types.
91 def with_all_of( *component_types )
92 return self.dup_with( all_of: component_types.flatten )
93 end
with_none_of( *component_types )
Return a dup of this Aspect that also requires that matching entities have none of the given component_types.
99 def with_none_of( *component_types )
100 return self.dup_with( none_of: component_types.flatten )
101 end
with_one_of( *component_types )
Return a dup of this Aspect that also requires that matching entities have at least one of the given component_types.
83 def with_one_of( *component_types )
84 return self.dup_with( one_of: component_types.flatten )
85 end
Protected Instance Methods
Return a String describing the components matching entities must have all of.
184 def all_of_description
185 return nil if self.all_of.empty?
186 return " with all of: %s" % [ self.all_of.map(&:name).join(', ') ]
187 end
dup_with( one_of: [], all_of: [], none_of: [] )
Return a copy of the receiver with the specified additional required and excluded components.
199 def dup_with( one_of: [], all_of: [], none_of: [] )
200 self.log.debug "Making dup of %p with one_of: %p, all_of: %p, none_of: %p" %
201 [ self, one_of, all_of, none_of ]
202
203 copy = self.dup
204 copy.one_of.merge( one_of )
205 copy.all_of.merge( all_of )
206 copy.none_of.merge( none_of )
207
208 self.log.debug " dup is: %p" % [ copy ]
209 return copy
210 end
Return the detail part of the #inspect output.
157 def inspect_details
158 parts = []
159 parts << self.one_of_description
160 parts << self.all_of_description
161 parts << self.none_of_description
162 parts.compact!
163
164 str = "matching entities"
165 if parts.empty?
166 str << " with any components"
167 else
168 str << parts.join( ', ' )
169 end
170
171 return str
172 end
Return a String describing the components matching entities must not have any of.
191 def none_of_description
192 return nil if self.none_of.empty?
193 return " with none of: %s" % [ self.none_of.map(&:name).join(', ') ]
194 end
Return a String describing the components matching entities must have at least one of.
177 def one_of_description
178 return nil if self.one_of.empty?
179 return " with at least one of: %s" % [ self.one_of.map(&:name).join(', ') ]
180 end