5
5
pub use bevy_ecs_macros:: Bundle ;
6
6
7
7
use crate :: {
8
- archetype:: { AddBundle , Archetype , ArchetypeId , Archetypes , ComponentStatus } ,
8
+ archetype:: {
9
+ Archetype , ArchetypeId , Archetypes , BundleComponentStatus , ComponentStatus ,
10
+ SpawnBundleStatus ,
11
+ } ,
9
12
component:: { Component , ComponentId , ComponentTicks , Components , StorageType } ,
10
13
entity:: { Entities , Entity , EntityLocation } ,
11
14
storage:: { SparseSetIndex , SparseSets , Storages , Table } ,
@@ -340,13 +343,10 @@ impl BundleInfo {
340
343
) -> BundleSpawner < ' a , ' b > {
341
344
let new_archetype_id =
342
345
self . add_bundle_to_archetype ( archetypes, storages, components, ArchetypeId :: EMPTY ) ;
343
- let ( empty_archetype, archetype) =
344
- archetypes. get_2_mut ( ArchetypeId :: EMPTY , new_archetype_id) ;
346
+ let archetype = & mut archetypes[ new_archetype_id] ;
345
347
let table = & mut storages. tables [ archetype. table_id ( ) ] ;
346
- let add_bundle = empty_archetype. edges ( ) . get_add_bundle ( self . id ( ) ) . unwrap ( ) ;
347
348
BundleSpawner {
348
349
archetype,
349
- add_bundle,
350
350
bundle_info : self ,
351
351
table,
352
352
entities,
@@ -355,16 +355,29 @@ impl BundleInfo {
355
355
}
356
356
}
357
357
358
+ /// This writes components from a given [`Bundle`] to the given entity.
359
+ ///
358
360
/// # Safety
361
+ ///
362
+ /// `bundle_component_status` must return the "correct" [`ComponentStatus`] for each component
363
+ /// in the [`Bundle`], with respect to the entity's original archetype (prior to the bundle being added)
364
+ /// For example, if the original archetype already has `ComponentA` and `T` also has `ComponentA`, the status
365
+ /// should be `Mutated`. If the original archetype does not have `ComponentA`, the status should be `Added`.
366
+ /// When "inserting" a bundle into an existing entity, [`AddBundle`](crate::archetype::AddBundle)
367
+ /// should be used, which will report `Added` vs `Mutated` status based on the current archetype's structure.
368
+ /// When spawning a bundle, [`SpawnBundleStatus`] can be used instead, which removes the need
369
+ /// to look up the [`AddBundle`](crate::archetype::AddBundle) in the archetype graph, which requires
370
+ /// ownership of the entity's current archetype.
371
+ ///
359
372
/// `table` must be the "new" table for `entity`. `table_row` must have space allocated for the
360
373
/// `entity`, `bundle` must match this [`BundleInfo`]'s type
361
374
#[ inline]
362
375
#[ allow( clippy:: too_many_arguments) ]
363
- unsafe fn write_components < T : Bundle > (
376
+ unsafe fn write_components < T : Bundle , S : BundleComponentStatus > (
364
377
& self ,
365
378
table : & mut Table ,
366
379
sparse_sets : & mut SparseSets ,
367
- add_bundle : & AddBundle ,
380
+ bundle_component_status : & S ,
368
381
entity : Entity ,
369
382
table_row : usize ,
370
383
change_tick : u32 ,
@@ -378,7 +391,8 @@ impl BundleInfo {
378
391
match self . storage_types [ bundle_component] {
379
392
StorageType :: Table => {
380
393
let column = table. get_column_mut ( component_id) . unwrap ( ) ;
381
- match add_bundle. bundle_status . get_unchecked ( bundle_component) {
394
+ // SAFETY: bundle_component is a valid index for this bundle
395
+ match bundle_component_status. get_status ( bundle_component) {
382
396
ComponentStatus :: Added => {
383
397
column. initialize (
384
398
table_row,
@@ -624,7 +638,6 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
624
638
pub ( crate ) struct BundleSpawner < ' a , ' b > {
625
639
pub ( crate ) archetype : & ' a mut Archetype ,
626
640
pub ( crate ) entities : & ' a mut Entities ,
627
- add_bundle : & ' a AddBundle ,
628
641
bundle_info : & ' b BundleInfo ,
629
642
table : & ' a mut Table ,
630
643
sparse_sets : & ' a mut SparseSets ,
@@ -649,7 +662,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> {
649
662
self . bundle_info . write_components (
650
663
self . table ,
651
664
self . sparse_sets ,
652
- self . add_bundle ,
665
+ & SpawnBundleStatus ,
653
666
entity,
654
667
table_row,
655
668
self . change_tick ,
0 commit comments