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.
45 def self::for_archetype( archetype )
46 return archetype.from_aspect if archetype.from_aspect
47 return self.new.with_all_of( archetype.components.keys )
48 end
new( one_of: [], all_of: [], none_of: [] )
Create a new empty Aspect
52 def initialize( one_of: [], all_of: [], none_of: [] )
53 @one_of = Set.new( one_of )
54 @all_of = Set.new( all_of )
55 @none_of = Set.new( none_of )
56 end
with_all_of( *component_types )
Return a new Aspect that will match entities with all of the specified component_types.
30 def self::with_all_of( *component_types )
31 return self.new( all_of: component_types.flatten )
32 end
with_none_of( *component_types )
Return a new Aspect that will match entities with none of the specified component_types.
37 def self::with_none_of( *component_types )
38 return self.new( none_of: component_types.flatten )
39 end
with_one_of( *component_types )
Return a new Aspect that will match entities with at least one of the specified component_types.
23 def self::with_one_of( *component_types )
24 return self.new( one_of: component_types.flatten )
25 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.
148 def archetype
149 return Chione::Archetype.from_aspect( self )
150 end
Returns true if the receiver is an empty aspect, i.e., matches all entities.
107 def empty?
108 return self.one_of.empty? && self.all_of.empty? && self.none_of.empty?
109 end
Copy constructor.
60 def initialize_copy( other )
61 super
62 @one_of = @one_of.dup
63 @all_of = @all_of.dup
64 @none_of = @none_of.dup
65 end
matches?( component_hash )
Returns true if the components contained in the specified component_hash match the Aspect’s specifications.
114 def matches?( component_hash )
115 return true if self.empty?
116
117 component_hash = component_hash.components if component_hash.respond_to?( :components )
118
119 return false unless self.one_of.empty? ||
120 self.one_of.any? {|component| component_hash.key?(component) }
121 return false unless self.none_of.none? {|component| component_hash.key?(component) }
122 return false unless self.all_of.all? {|component| component_hash.key?(component) }
123
124 return true
125 end
matching_entities( entity_hash )
Given an entity_hash keyed by Component class, return the subset of values matching the receiving Aspect.
131 def matching_entities( entity_hash )
132 initial_set = if self.one_of.empty?
133 entity_hash.values
134 else
135 entity_hash.values_at( *self.one_of )
136 end
137
138 with_one = initial_set.reduce( :| ) || Set.new
139 with_all = entity_hash.values_at( *self.all_of ).reduce( with_one, :& )
140 without_any = entity_hash.values_at( *self.none_of ).reduce( with_all, :- )
141
142 return without_any
143 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.
92 def with_all_of( *component_types )
93 return self.dup_with( all_of: component_types.flatten )
94 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.
100 def with_none_of( *component_types )
101 return self.dup_with( none_of: component_types.flatten )
102 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.
84 def with_one_of( *component_types )
85 return self.dup_with( one_of: component_types.flatten )
86 end
Protected Instance Methods
Return a String describing the components matching entities must have all of.
185 def all_of_description
186 return nil if self.all_of.empty?
187 return " with all of: %s" % [ self.all_of.map(&:name).join(', ') ]
188 end
dup_with( one_of: [], all_of: [], none_of: [] )
Return a copy of the receiver with the specified additional required and excluded components.
200 def dup_with( one_of: [], all_of: [], none_of: [] )
201 self.log.debug "Making dup of %p with one_of: %p, all_of: %p, none_of: %p" %
202 [ self, one_of, all_of, none_of ]
203
204 copy = self.dup
205 copy.one_of.merge( one_of )
206 copy.all_of.merge( all_of )
207 copy.none_of.merge( none_of )
208
209 self.log.debug " dup is: %p" % [ copy ]
210 return copy
211 end
Return the detail part of the #inspect output.
158 def inspect_details
159 parts = []
160 parts << self.one_of_description
161 parts << self.all_of_description
162 parts << self.none_of_description
163 parts.compact!
164
165 str = "matching entities"
166 if parts.empty?
167 str << " with any components"
168 else
169 str << parts.join( ', ' )
170 end
171
172 return str
173 end
Return a String describing the components matching entities must not have any of.
192 def none_of_description
193 return nil if self.none_of.empty?
194 return " with none of: %s" % [ self.none_of.map(&:name).join(', ') ]
195 end
Return a String describing the components matching entities must have at least one of.
178 def one_of_description
179 return nil if self.one_of.empty?
180 return " with at least one of: %s" % [ self.one_of.map(&:name).join(', ') ]
181 end