move get_insert_bundle_info (#2508)
I had to move this out in my relations PR and its causing a large diff so I figure I could just do this separately
This commit is contained in:
parent
2c28331297
commit
ba2916c45a
@ -189,76 +189,76 @@ impl<'w> EntityMut<'w> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety:
|
||||||
|
/// Partially moves the entity to a new archetype based on the provided bundle info
|
||||||
|
/// You must handle the other part of moving the entity yourself
|
||||||
|
unsafe fn get_insert_bundle_info<'a>(
|
||||||
|
entities: &mut Entities,
|
||||||
|
archetypes: &'a mut Archetypes,
|
||||||
|
components: &mut Components,
|
||||||
|
storages: &mut Storages,
|
||||||
|
bundle_info: &BundleInfo,
|
||||||
|
current_location: EntityLocation,
|
||||||
|
entity: Entity,
|
||||||
|
) -> (&'a Archetype, &'a Vec<ComponentStatus>, EntityLocation) {
|
||||||
|
// SAFE: component ids in `bundle_info` and self.location are valid
|
||||||
|
let new_archetype_id = add_bundle_to_archetype(
|
||||||
|
archetypes,
|
||||||
|
storages,
|
||||||
|
components,
|
||||||
|
current_location.archetype_id,
|
||||||
|
bundle_info,
|
||||||
|
);
|
||||||
|
if new_archetype_id == current_location.archetype_id {
|
||||||
|
let archetype = &archetypes[current_location.archetype_id];
|
||||||
|
let edge = archetype.edges().get_add_bundle(bundle_info.id).unwrap();
|
||||||
|
(archetype, &edge.bundle_status, current_location)
|
||||||
|
} else {
|
||||||
|
let (old_table_row, old_table_id) = {
|
||||||
|
let old_archetype = &mut archetypes[current_location.archetype_id];
|
||||||
|
let result = old_archetype.swap_remove(current_location.index);
|
||||||
|
if let Some(swapped_entity) = result.swapped_entity {
|
||||||
|
entities.meta[swapped_entity.id as usize].location = current_location;
|
||||||
|
}
|
||||||
|
(result.table_row, old_archetype.table_id())
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_table_id = archetypes[new_archetype_id].table_id();
|
||||||
|
|
||||||
|
let new_location = if old_table_id == new_table_id {
|
||||||
|
archetypes[new_archetype_id].allocate(entity, old_table_row)
|
||||||
|
} else {
|
||||||
|
let (old_table, new_table) = storages.tables.get_2_mut(old_table_id, new_table_id);
|
||||||
|
// PERF: store "non bundle" components in edge, then just move those to avoid
|
||||||
|
// redundant copies
|
||||||
|
let move_result = old_table.move_to_superset_unchecked(old_table_row, new_table);
|
||||||
|
|
||||||
|
let new_location =
|
||||||
|
archetypes[new_archetype_id].allocate(entity, move_result.new_row);
|
||||||
|
// if an entity was moved into this entity's table spot, update its table row
|
||||||
|
if let Some(swapped_entity) = move_result.swapped_entity {
|
||||||
|
let swapped_location = entities.get(swapped_entity).unwrap();
|
||||||
|
archetypes[swapped_location.archetype_id]
|
||||||
|
.set_entity_table_row(swapped_location.index, old_table_row);
|
||||||
|
}
|
||||||
|
new_location
|
||||||
|
};
|
||||||
|
|
||||||
|
entities.meta[entity.id as usize].location = new_location;
|
||||||
|
let (old_archetype, new_archetype) =
|
||||||
|
archetypes.get_2_mut(current_location.archetype_id, new_archetype_id);
|
||||||
|
let edge = old_archetype
|
||||||
|
.edges()
|
||||||
|
.get_add_bundle(bundle_info.id)
|
||||||
|
.unwrap();
|
||||||
|
(&*new_archetype, &edge.bundle_status, new_location)
|
||||||
|
|
||||||
|
// Sparse set components are intentionally ignored here. They don't need to move
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: move relevant methods to World (add/remove bundle)
|
// TODO: move relevant methods to World (add/remove bundle)
|
||||||
pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self {
|
pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self {
|
||||||
// Use a non-generic function to cut down on monomorphization
|
|
||||||
unsafe fn get_insert_bundle_info<'a>(
|
|
||||||
entities: &mut Entities,
|
|
||||||
archetypes: &'a mut Archetypes,
|
|
||||||
components: &mut Components,
|
|
||||||
storages: &mut Storages,
|
|
||||||
bundle_info: &BundleInfo,
|
|
||||||
current_location: EntityLocation,
|
|
||||||
entity: Entity,
|
|
||||||
) -> (&'a Archetype, &'a Vec<ComponentStatus>, EntityLocation) {
|
|
||||||
// SAFE: component ids in `bundle_info` and self.location are valid
|
|
||||||
let new_archetype_id = add_bundle_to_archetype(
|
|
||||||
archetypes,
|
|
||||||
storages,
|
|
||||||
components,
|
|
||||||
current_location.archetype_id,
|
|
||||||
bundle_info,
|
|
||||||
);
|
|
||||||
if new_archetype_id == current_location.archetype_id {
|
|
||||||
let archetype = &archetypes[current_location.archetype_id];
|
|
||||||
let edge = archetype.edges().get_add_bundle(bundle_info.id).unwrap();
|
|
||||||
(archetype, &edge.bundle_status, current_location)
|
|
||||||
} else {
|
|
||||||
let (old_table_row, old_table_id) = {
|
|
||||||
let old_archetype = &mut archetypes[current_location.archetype_id];
|
|
||||||
let result = old_archetype.swap_remove(current_location.index);
|
|
||||||
if let Some(swapped_entity) = result.swapped_entity {
|
|
||||||
entities.meta[swapped_entity.id as usize].location = current_location;
|
|
||||||
}
|
|
||||||
(result.table_row, old_archetype.table_id())
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_table_id = archetypes[new_archetype_id].table_id();
|
|
||||||
|
|
||||||
let new_location = if old_table_id == new_table_id {
|
|
||||||
archetypes[new_archetype_id].allocate(entity, old_table_row)
|
|
||||||
} else {
|
|
||||||
let (old_table, new_table) =
|
|
||||||
storages.tables.get_2_mut(old_table_id, new_table_id);
|
|
||||||
// PERF: store "non bundle" components in edge, then just move those to avoid
|
|
||||||
// redundant copies
|
|
||||||
let move_result =
|
|
||||||
old_table.move_to_superset_unchecked(old_table_row, new_table);
|
|
||||||
|
|
||||||
let new_location =
|
|
||||||
archetypes[new_archetype_id].allocate(entity, move_result.new_row);
|
|
||||||
// if an entity was moved into this entity's table spot, update its table row
|
|
||||||
if let Some(swapped_entity) = move_result.swapped_entity {
|
|
||||||
let swapped_location = entities.get(swapped_entity).unwrap();
|
|
||||||
archetypes[swapped_location.archetype_id]
|
|
||||||
.set_entity_table_row(swapped_location.index, old_table_row);
|
|
||||||
}
|
|
||||||
new_location
|
|
||||||
};
|
|
||||||
|
|
||||||
entities.meta[entity.id as usize].location = new_location;
|
|
||||||
let (old_archetype, new_archetype) =
|
|
||||||
archetypes.get_2_mut(current_location.archetype_id, new_archetype_id);
|
|
||||||
let edge = old_archetype
|
|
||||||
.edges()
|
|
||||||
.get_add_bundle(bundle_info.id)
|
|
||||||
.unwrap();
|
|
||||||
(&*new_archetype, &edge.bundle_status, new_location)
|
|
||||||
|
|
||||||
// Sparse set components are intentionally ignored here. They don't need to move
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let change_tick = self.world.change_tick();
|
let change_tick = self.world.change_tick();
|
||||||
let bundle_info = self
|
let bundle_info = self
|
||||||
.world
|
.world
|
||||||
@ -266,7 +266,7 @@ impl<'w> EntityMut<'w> {
|
|||||||
.init_info::<T>(&mut self.world.components);
|
.init_info::<T>(&mut self.world.components);
|
||||||
|
|
||||||
let (archetype, bundle_status, new_location) = unsafe {
|
let (archetype, bundle_status, new_location) = unsafe {
|
||||||
get_insert_bundle_info(
|
Self::get_insert_bundle_info(
|
||||||
&mut self.world.entities,
|
&mut self.world.entities,
|
||||||
&mut self.world.archetypes,
|
&mut self.world.archetypes,
|
||||||
&mut self.world.components,
|
&mut self.world.components,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user