1
+ use bevy_utils:: HashMap ;
2
+ use bevy_utils:: StableHashMap ;
3
+
1
4
use crate :: {
2
5
bundle:: BundleId ,
3
6
component:: { ComponentId , StorageType } ,
4
7
entity:: { Entity , EntityLocation } ,
5
- storage:: { Column , SparseArray , SparseSet , SparseSetIndex , TableId } ,
8
+ storage:: { Column , SparseSet , SparseSetIndex , TableId } ,
6
9
} ;
7
10
use std:: {
8
11
borrow:: Cow ,
9
- collections:: HashMap ,
10
12
hash:: Hash ,
11
13
ops:: { Index , IndexMut } ,
12
14
} ;
@@ -48,15 +50,41 @@ pub struct AddBundle {
48
50
49
51
#[ derive( Default ) ]
50
52
pub struct Edges {
51
- pub add_bundle : SparseArray < BundleId , AddBundle > ,
52
- pub remove_bundle : SparseArray < BundleId , Option < ArchetypeId > > ,
53
- pub remove_bundle_intersection : SparseArray < BundleId , Option < ArchetypeId > > ,
53
+ pub add_bundle : HashMap < BundleId , AddBundle > ,
54
+ pub remove_bundle : HashMap < BundleId , Option < ArchetypeId > > ,
55
+ pub remove_bundle_intersection : HashMap < BundleId , Option < ArchetypeId > > ,
54
56
}
55
57
56
58
impl Edges {
59
+ pub fn debug_ram_usage ( & self ) -> usize {
60
+ use std:: mem:: size_of;
61
+
62
+ let mut size = size_of :: < Edges > ( ) ;
63
+
64
+ let usage_of_hm = |cap : usize , k, v| ( cap * 11 / 10 ) . next_power_of_two ( ) * ( k + v + 8 ) ;
65
+
66
+ size += usage_of_hm (
67
+ self . add_bundle . capacity ( ) ,
68
+ size_of :: < BundleId > ( ) ,
69
+ size_of :: < AddBundle > ( ) ,
70
+ ) ;
71
+ size += usage_of_hm (
72
+ self . remove_bundle . capacity ( ) ,
73
+ size_of :: < BundleId > ( ) ,
74
+ size_of :: < Option < ArchetypeId > > ( ) ,
75
+ ) ;
76
+ size += usage_of_hm (
77
+ self . remove_bundle_intersection . capacity ( ) ,
78
+ size_of :: < BundleId > ( ) ,
79
+ size_of :: < Option < ArchetypeId > > ( ) ,
80
+ ) ;
81
+
82
+ size
83
+ }
84
+
57
85
#[ inline]
58
86
pub fn get_add_bundle ( & self , bundle_id : BundleId ) -> Option < & AddBundle > {
59
- self . add_bundle . get ( bundle_id)
87
+ self . add_bundle . get ( & bundle_id)
60
88
}
61
89
62
90
#[ inline]
@@ -77,7 +105,7 @@ impl Edges {
77
105
78
106
#[ inline]
79
107
pub fn get_remove_bundle ( & self , bundle_id : BundleId ) -> Option < Option < ArchetypeId > > {
80
- self . remove_bundle . get ( bundle_id) . cloned ( )
108
+ self . remove_bundle . get ( & bundle_id) . cloned ( )
81
109
}
82
110
83
111
#[ inline]
@@ -90,7 +118,7 @@ impl Edges {
90
118
& self ,
91
119
bundle_id : BundleId ,
92
120
) -> Option < Option < ArchetypeId > > {
93
- self . remove_bundle_intersection . get ( bundle_id) . cloned ( )
121
+ self . remove_bundle_intersection . get ( & bundle_id) . cloned ( )
94
122
}
95
123
96
124
#[ inline]
@@ -124,54 +152,103 @@ pub struct Archetype {
124
152
entities : Vec < Entity > ,
125
153
edges : Edges ,
126
154
table_info : TableInfo ,
127
- table_components : Cow < ' static , [ ComponentId ] > ,
128
- sparse_set_components : Cow < ' static , [ ComponentId ] > ,
155
+ table_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
156
+ sparse_set_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
129
157
pub ( crate ) unique_components : SparseSet < ComponentId , Column > ,
130
158
pub ( crate ) components : SparseSet < ComponentId , ArchetypeComponentInfo > ,
159
+ pub ( crate ) relations : SparseSet < ComponentId , StableHashMap < Entity , ArchetypeComponentInfo > > ,
131
160
}
132
161
133
162
impl Archetype {
163
+ pub fn debug_ram_usage ( & self ) -> ( usize , usize ) {
164
+ use std:: mem:: size_of;
165
+ let mut size = size_of :: < Archetype > ( ) ;
166
+
167
+ if let Cow :: Owned ( owned) = & self . table_components {
168
+ size += size_of :: < ( ComponentId , Option < Entity > ) > ( ) * owned. len ( ) ;
169
+ }
170
+ if let Cow :: Owned ( owned) = & self . sparse_set_components {
171
+ size += size_of :: < ( ComponentId , Option < Entity > ) > ( ) * owned. len ( ) ;
172
+ }
173
+
174
+ size += size_of :: < ArchetypeComponentInfo > ( ) * self . components . dense_len ( ) ;
175
+ size += size_of :: < ComponentId > ( ) * self . components . indices_len ( ) ;
176
+ size += size_of :: < Option < usize > > ( ) * self . components . sparse_len ( ) ;
177
+
178
+ size += size_of :: < ComponentId > ( ) * self . relations . indices_len ( ) ;
179
+ size += size_of :: < Option < usize > > ( ) * self . relations . sparse_len ( ) ;
180
+
181
+ for v in self . relations . values ( ) {
182
+ let cap = v. capacity ( ) ;
183
+ let usage = ( cap * 11 / 10 ) . next_power_of_two ( )
184
+ * ( size_of :: < Entity > ( ) + size_of :: < ArchetypeComponentInfo > ( ) + 8 ) ;
185
+ size += usage;
186
+ }
187
+
188
+ size += size_of :: < Entity > ( ) * self . entities . len ( ) ;
189
+
190
+ ( size, self . edges . debug_ram_usage ( ) )
191
+ }
192
+
134
193
pub fn new (
135
194
id : ArchetypeId ,
136
195
table_id : TableId ,
137
- table_components : Cow < ' static , [ ComponentId ] > ,
138
- sparse_set_components : Cow < ' static , [ ComponentId ] > ,
196
+ table_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
197
+ sparse_set_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
139
198
table_archetype_components : Vec < ArchetypeComponentId > ,
140
199
sparse_set_archetype_components : Vec < ArchetypeComponentId > ,
141
200
) -> Self {
201
+ // FIXME(Relationships) sort out this capacity weirdness
142
202
let mut components =
143
203
SparseSet :: with_capacity ( table_components. len ( ) + sparse_set_components. len ( ) ) ;
144
- for ( component_id, archetype_component_id) in
204
+ let mut relations = SparseSet :: new ( ) ;
205
+ for ( ( component_id, target) , archetype_component_id) in
145
206
table_components. iter ( ) . zip ( table_archetype_components)
146
207
{
147
- components. insert (
148
- * component_id,
149
- ArchetypeComponentInfo {
150
- storage_type : StorageType :: Table ,
151
- archetype_component_id,
152
- } ,
153
- ) ;
208
+ let arch_comp_info = ArchetypeComponentInfo {
209
+ storage_type : StorageType :: Table ,
210
+ archetype_component_id,
211
+ } ;
212
+
213
+ match target {
214
+ None => {
215
+ components. insert ( * component_id, arch_comp_info) ;
216
+ }
217
+ Some ( target) => {
218
+ let set = relations. get_or_insert_with ( * component_id, StableHashMap :: default) ;
219
+ set. insert ( * target, arch_comp_info) ;
220
+ }
221
+ } ;
154
222
}
155
223
156
- for ( component_id, archetype_component_id) in sparse_set_components
224
+ for ( ( component_id, target ) , archetype_component_id) in sparse_set_components
157
225
. iter ( )
158
226
. zip ( sparse_set_archetype_components)
159
227
{
160
- components. insert (
161
- * component_id,
162
- ArchetypeComponentInfo {
163
- storage_type : StorageType :: SparseSet ,
164
- archetype_component_id,
165
- } ,
166
- ) ;
228
+ let arch_comp_info = ArchetypeComponentInfo {
229
+ storage_type : StorageType :: SparseSet ,
230
+ archetype_component_id,
231
+ } ;
232
+
233
+ match target {
234
+ None => {
235
+ components. insert ( * component_id, arch_comp_info) ;
236
+ }
237
+ Some ( target) => {
238
+ let set = relations. get_or_insert_with ( * component_id, StableHashMap :: default) ;
239
+ set. insert ( * target, arch_comp_info) ;
240
+ }
241
+ } ;
167
242
}
243
+
168
244
Self {
169
245
id,
170
246
table_info : TableInfo {
171
247
id : table_id,
172
248
entity_rows : Default :: default ( ) ,
173
249
} ,
174
250
components,
251
+ relations,
175
252
table_components,
176
253
sparse_set_components,
177
254
unique_components : SparseSet :: new ( ) ,
@@ -201,12 +278,12 @@ impl Archetype {
201
278
}
202
279
203
280
#[ inline]
204
- pub fn table_components ( & self ) -> & [ ComponentId ] {
281
+ pub fn table_components ( & self ) -> & [ ( ComponentId , Option < Entity > ) ] {
205
282
& self . table_components
206
283
}
207
284
208
285
#[ inline]
209
- pub fn sparse_set_components ( & self ) -> & [ ComponentId ] {
286
+ pub fn sparse_set_components ( & self ) -> & [ ( ComponentId , Option < Entity > ) ] {
210
287
& self . sparse_set_components
211
288
}
212
289
@@ -221,8 +298,17 @@ impl Archetype {
221
298
}
222
299
223
300
#[ inline]
224
- pub fn components ( & self ) -> impl Iterator < Item = ComponentId > + ' _ {
225
- self . components . indices ( )
301
+ pub fn components ( & self ) -> impl Iterator < Item = ( ComponentId , Option < Entity > ) > + ' _ {
302
+ self . components
303
+ . indices ( )
304
+ . map ( |kind| ( kind, None ) )
305
+ . chain ( self . relations . indices ( ) . flat_map ( move |component_id| {
306
+ self . relations
307
+ . get ( component_id)
308
+ . unwrap ( )
309
+ . keys ( )
310
+ . map ( move |target| ( component_id, Some ( * target) ) )
311
+ } ) )
226
312
}
227
313
228
314
#[ inline]
@@ -289,25 +375,50 @@ impl Archetype {
289
375
}
290
376
291
377
#[ inline]
292
- pub fn contains ( & self , component_id : ComponentId ) -> bool {
293
- self . components . contains ( component_id)
378
+ pub fn contains ( & self , component_id : ComponentId , target : Option < Entity > ) -> bool {
379
+ match target {
380
+ None => self . components . contains ( component_id) ,
381
+ Some ( target) => self
382
+ . relations
383
+ . get ( component_id)
384
+ . map ( |set| set. contains_key ( & target) )
385
+ . unwrap_or ( false ) ,
386
+ }
294
387
}
295
388
389
+ // FIXME(Relationships) technically the target is unnecessary here as all `KindId` have the same storage type
296
390
#[ inline]
297
- pub fn get_storage_type ( & self , component_id : ComponentId ) -> Option < StorageType > {
298
- self . components
299
- . get ( component_id)
300
- . map ( |info| info. storage_type )
391
+ pub fn get_storage_type (
392
+ & self ,
393
+ component_id : ComponentId ,
394
+ target : Option < Entity > ,
395
+ ) -> Option < StorageType > {
396
+ match target {
397
+ None => self . components . get ( component_id) ,
398
+ Some ( target) => self
399
+ . relations
400
+ . get ( component_id)
401
+ . and_then ( |set| set. get ( & target) ) ,
402
+ }
403
+ . map ( |info| info. storage_type )
301
404
}
302
405
303
406
#[ inline]
304
407
pub fn get_archetype_component_id (
305
408
& self ,
306
409
component_id : ComponentId ,
410
+ // FIXME(Relationships) treat archetype componnet id the same as component id maybe?? see other fixme
411
+ // then we oculd get rid of this `target` arg and same with fn above
412
+ target : Option < Entity > ,
307
413
) -> Option < ArchetypeComponentId > {
308
- self . components
309
- . get ( component_id)
310
- . map ( |info| info. archetype_component_id )
414
+ match target {
415
+ None => self . components . get ( component_id) ,
416
+ Some ( target) => self
417
+ . relations
418
+ . get ( component_id)
419
+ . and_then ( |set| set. get ( & target) ) ,
420
+ }
421
+ . map ( |info| info. archetype_component_id )
311
422
}
312
423
}
313
424
@@ -329,8 +440,8 @@ impl ArchetypeGeneration {
329
440
330
441
#[ derive( Hash , PartialEq , Eq ) ]
331
442
pub struct ArchetypeIdentity {
332
- table_components : Cow < ' static , [ ComponentId ] > ,
333
- sparse_set_components : Cow < ' static , [ ComponentId ] > ,
443
+ table_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
444
+ sparse_set_components : Cow < ' static , [ ( ComponentId , Option < Entity > ) ] > ,
334
445
}
335
446
336
447
#[ derive( Debug , Copy , Clone , Eq , PartialEq , Hash ) ]
@@ -453,6 +564,10 @@ impl Archetypes {
453
564
a : ArchetypeId ,
454
565
b : ArchetypeId ,
455
566
) -> ( & mut Archetype , & mut Archetype ) {
567
+ if a. 0 == b. 0 {
568
+ panic ! ( "both indexes were the same" ) ;
569
+ }
570
+
456
571
if a. index ( ) > b. index ( ) {
457
572
let ( b_slice, a_slice) = self . archetypes . split_at_mut ( a. index ( ) ) ;
458
573
( & mut a_slice[ 0 ] , & mut b_slice[ b. index ( ) ] )
@@ -475,8 +590,8 @@ impl Archetypes {
475
590
pub ( crate ) fn get_id_or_insert (
476
591
& mut self ,
477
592
table_id : TableId ,
478
- table_components : Vec < ComponentId > ,
479
- sparse_set_components : Vec < ComponentId > ,
593
+ table_components : Vec < ( ComponentId , Option < Entity > ) > ,
594
+ sparse_set_components : Vec < ( ComponentId , Option < Entity > ) > ,
480
595
) -> ArchetypeId {
481
596
let table_components = Cow :: from ( table_components) ;
482
597
let sparse_set_components = Cow :: from ( sparse_set_components) ;
0 commit comments