@@ -2,7 +2,7 @@ use crate::{
22 archetype:: { Archetype , ArchetypeId , Archetypes , ComponentStatus } ,
33 bundle:: { Bundle , BundleInfo } ,
44 component:: { Component , ComponentId , ComponentTicks , Components , StorageType } ,
5- entity:: { Entity , EntityLocation } ,
5+ entity:: { Entities , Entity , EntityLocation } ,
66 storage:: { SparseSet , Storages } ,
77 world:: { Mut , World } ,
88} ;
@@ -182,7 +182,6 @@ impl<'w> EntityMut<'w> {
182182 } )
183183 }
184184
185- // TODO: factor out non-generic part to cut down on monomorphization (just check perf)
186185 // TODO: move relevant methods to World (add/remove bundle)
187186 pub fn insert_bundle < T : Bundle > ( & mut self , bundle : T ) -> & mut Self {
188187 let entity = self . entity ;
@@ -195,19 +194,28 @@ impl<'w> EntityMut<'w> {
195194 let bundle_info = self . world . bundles . init_info :: < T > ( components) ;
196195 let current_location = self . location ;
197196
198- let ( archetype, bundle_status, archetype_index) = unsafe {
197+ // Use a non-generic function to cut down on monomorphization
198+ unsafe fn get_insert_bundle_info < ' a > (
199+ entities : & mut Entities ,
200+ archetypes : & ' a mut Archetypes ,
201+ components : & mut Components ,
202+ storages : & mut Storages ,
203+ bundle_info : & BundleInfo ,
204+ current_location : EntityLocation ,
205+ entity : Entity ,
206+ ) -> ( & ' a Archetype , & ' a Vec < ComponentStatus > , EntityLocation ) {
199207 // SAFE: component ids in `bundle_info` and self.location are valid
200208 let new_archetype_id = add_bundle_to_archetype (
201209 archetypes,
202210 storages,
203211 components,
204- self . location . archetype_id ,
212+ current_location . archetype_id ,
205213 bundle_info,
206214 ) ;
207215 if new_archetype_id == current_location. archetype_id {
208216 let archetype = & archetypes[ current_location. archetype_id ] ;
209217 let edge = archetype. edges ( ) . get_add_bundle ( bundle_info. id ) . unwrap ( ) ;
210- ( archetype, & edge. bundle_status , current_location. index )
218+ ( archetype, & edge. bundle_status , current_location)
211219 } else {
212220 let ( old_table_row, old_table_id) = {
213221 let old_archetype = & mut archetypes[ current_location. archetype_id ] ;
@@ -241,22 +249,34 @@ impl<'w> EntityMut<'w> {
241249 new_location
242250 } ;
243251
244- self . location = new_location;
245- entities. meta [ self . entity . id as usize ] . location = new_location;
252+ entities. meta [ entity. id as usize ] . location = new_location;
246253 let ( old_archetype, new_archetype) =
247254 archetypes. get_2_mut ( current_location. archetype_id , new_archetype_id) ;
248255 let edge = old_archetype
249256 . edges ( )
250257 . get_add_bundle ( bundle_info. id )
251258 . unwrap ( ) ;
252- ( & * new_archetype, & edge. bundle_status , new_location. index )
259+ ( & * new_archetype, & edge. bundle_status , new_location)
253260
254261 // Sparse set components are intentionally ignored here. They don't need to move
255262 }
263+ }
264+
265+ let ( archetype, bundle_status, new_location) = unsafe {
266+ get_insert_bundle_info (
267+ entities,
268+ archetypes,
269+ components,
270+ storages,
271+ bundle_info,
272+ current_location,
273+ entity,
274+ )
256275 } ;
276+ self . location = new_location;
257277
258278 let table = & storages. tables [ archetype. table_id ( ) ] ;
259- let table_row = archetype. entity_table_row ( archetype_index ) ;
279+ let table_row = archetype. entity_table_row ( new_location . index ) ;
260280 // SAFE: table row is valid
261281 unsafe {
262282 bundle_info. write_components (
0 commit comments