@@ -2,7 +2,7 @@ use crate::{
2
2
archetype:: { Archetype , ArchetypeId , Archetypes , ComponentStatus } ,
3
3
bundle:: { Bundle , BundleInfo } ,
4
4
component:: { Component , ComponentId , ComponentTicks , Components , StorageType } ,
5
- entity:: { Entity , EntityLocation } ,
5
+ entity:: { Entities , Entity , EntityLocation } ,
6
6
storage:: { SparseSet , Storages } ,
7
7
world:: { Mut , World } ,
8
8
} ;
@@ -182,7 +182,6 @@ impl<'w> EntityMut<'w> {
182
182
} )
183
183
}
184
184
185
- // TODO: factor out non-generic part to cut down on monomorphization (just check perf)
186
185
// TODO: move relevant methods to World (add/remove bundle)
187
186
pub fn insert_bundle < T : Bundle > ( & mut self , bundle : T ) -> & mut Self {
188
187
let entity = self . entity ;
@@ -195,19 +194,28 @@ impl<'w> EntityMut<'w> {
195
194
let bundle_info = self . world . bundles . init_info :: < T > ( components) ;
196
195
let current_location = self . location ;
197
196
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 ) {
199
207
// SAFE: component ids in `bundle_info` and self.location are valid
200
208
let new_archetype_id = add_bundle_to_archetype (
201
209
archetypes,
202
210
storages,
203
211
components,
204
- self . location . archetype_id ,
212
+ current_location . archetype_id ,
205
213
bundle_info,
206
214
) ;
207
215
if new_archetype_id == current_location. archetype_id {
208
216
let archetype = & archetypes[ current_location. archetype_id ] ;
209
217
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)
211
219
} else {
212
220
let ( old_table_row, old_table_id) = {
213
221
let old_archetype = & mut archetypes[ current_location. archetype_id ] ;
@@ -241,22 +249,34 @@ impl<'w> EntityMut<'w> {
241
249
new_location
242
250
} ;
243
251
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;
246
253
let ( old_archetype, new_archetype) =
247
254
archetypes. get_2_mut ( current_location. archetype_id , new_archetype_id) ;
248
255
let edge = old_archetype
249
256
. edges ( )
250
257
. get_add_bundle ( bundle_info. id )
251
258
. unwrap ( ) ;
252
- ( & * new_archetype, & edge. bundle_status , new_location. index )
259
+ ( & * new_archetype, & edge. bundle_status , new_location)
253
260
254
261
// Sparse set components are intentionally ignored here. They don't need to move
255
262
}
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
+ )
256
275
} ;
276
+ self . location = new_location;
257
277
258
278
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 ) ;
260
280
// SAFE: table row is valid
261
281
unsafe {
262
282
bundle_info. write_components (
0 commit comments