Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Extract monomorphic get_insert_bundle_info function #1910

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
archetype::{Archetype, ArchetypeId, Archetypes, ComponentStatus},
bundle::{Bundle, BundleInfo},
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
entity::{Entity, EntityLocation},
entity::{Entities, Entity, EntityLocation},
storage::{SparseSet, Storages},
world::{Mut, World},
};
Expand Down Expand Up @@ -182,7 +182,6 @@ impl<'w> EntityMut<'w> {
})
}

// TODO: factor out non-generic part to cut down on monomorphization (just check perf)
// TODO: move relevant methods to World (add/remove bundle)
pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self {
let entity = self.entity;
Expand All @@ -195,19 +194,28 @@ impl<'w> EntityMut<'w> {
let bundle_info = self.world.bundles.init_info::<T>(components);
let current_location = self.location;

let (archetype, bundle_status, archetype_index) = unsafe {
// 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,
self.location.archetype_id,
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.index)
(archetype, &edge.bundle_status, current_location)
} else {
let (old_table_row, old_table_id) = {
let old_archetype = &mut archetypes[current_location.archetype_id];
Expand Down Expand Up @@ -241,22 +249,34 @@ impl<'w> EntityMut<'w> {
new_location
};

self.location = new_location;
entities.meta[self.entity.id as usize].location = 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.index)
(&*new_archetype, &edge.bundle_status, new_location)

// Sparse set components are intentionally ignored here. They don't need to move
}
}

let (archetype, bundle_status, new_location) = unsafe {
get_insert_bundle_info(
entities,
archetypes,
components,
storages,
bundle_info,
current_location,
entity,
)
};
self.location = new_location;

let table = &storages.tables[archetype.table_id()];
let table_row = archetype.entity_table_row(archetype_index);
let table_row = archetype.entity_table_row(new_location.index);
// SAFE: table row is valid
unsafe {
bundle_info.write_components(
Expand Down