unsafe fn remove_bundle_from_archetype(
    archetypes: &mut Archetypes,
    storages: &mut Storages,
    components: &mut Components,
    archetype_id: ArchetypeId,
    bundle_info: &BundleInfo,
    intersection: bool,
) -> Option<ArchetypeId> {
    // check the archetype graph to see if the Bundle has been removed from this archetype in the
    // past
    let remove_bundle_result = {
        let current_archetype = &mut archetypes[archetype_id];
        if intersection {
            current_archetype
                .edges()
                .get_remove_bundle_intersection(bundle_info.id)
        } else {
            current_archetype.edges().get_remove_bundle(bundle_info.id)
        }
    };
    let result = if let Some(result) = remove_bundle_result {
        // this Bundle removal result is cached. just return that!
        result
    } else {
        let mut next_table_components;
        let mut next_sparse_set_components;
        let next_table_id;
        {
            let current_archetype = &mut archetypes[archetype_id];
            let mut removed_table_components = Vec::new();
            let mut removed_sparse_set_components = Vec::new();
            for component_id in bundle_info.component_ids.iter().cloned() {
                if current_archetype.contains(component_id) {
                    // SAFE: bundle components were already initialized by bundles.get_info
                    let component_info = components.get_info_unchecked(component_id);
                    match component_info.storage_type() {
                        StorageType::Table => removed_table_components.push(component_id),
                        StorageType::SparseSet => removed_sparse_set_components.push(component_id),
                    }
                } else if !intersection {
                    // a component in the bundle was not present in the entity's archetype, so this
                    // removal is invalid cache the result in the archetype
                    // graph
                    current_archetype
                        .edges_mut()
                        .insert_remove_bundle(bundle_info.id, None);
                    return None;
                }
            }

            // sort removed components so we can do an efficient "sorted remove". archetype
            // components are already sorted
            removed_table_components.sort();
            removed_sparse_set_components.sort();
            next_table_components = current_archetype.table_components().to_vec();
            next_sparse_set_components = current_archetype.sparse_set_components().to_vec();
            sorted_remove(&mut next_table_components, &removed_table_components);
            sorted_remove(
                &mut next_sparse_set_components,
                &removed_sparse_set_components,
            );

            next_table_id = if removed_table_components.is_empty() {
                current_archetype.table_id()
            } else {
                // SAFE: all components in next_table_components exist
                storages
                    .tables
                    .get_id_or_insert(&next_table_components, components)
            };
        }

        let new_archetype_id = archetypes.get_id_or_insert(
            next_table_id,
            next_table_components,
            next_sparse_set_components,
        );
        Some(new_archetype_id)
    };
    let current_archetype = &mut archetypes[archetype_id];
    // cache the result in an edge
    if intersection {
        current_archetype
            .edges_mut()
            .insert_remove_bundle_intersection(bundle_info.id, result);
    } else {
        current_archetype
            .edges_mut()
            .insert_remove_bundle(bundle_info.id, result);
    }
    result
}
/// Removes a bundle from the given archetype and returns the resulting archetype (or None if the
/// removal was invalid). in the event that adding the given bundle does not result in an Archetype
/// change. Results are cached in the Archetype Graph to avoid redundant work.
/// if `intersection` is false, attempting to remove a bundle with components _not_ contained in the
/// current archetype will fail, returning None. if `intersection` is true, components in the bundle
/// but not in the current archetype will be ignored
///
/// # Safety
/// `archetype_id` must exist and components in `bundle_info` must exist
Removes a bundle from the given archetype and returns the resulting archetype (or None if the
removal was invalid). in the event that adding the given bundle does not result in an Archetype
change. Results are cached in the Archetype Graph to avoid redundant work.
if `intersection` is false, attempting to remove a bundle with components _not_ contained in the
current archetype will fail, returning None. if `intersection` is true, components in the bundle
but not in the current archetype will be ignored
Removes a bundle from the given archetype and returns the resulting archetype ( or None if the removal was invalid ) . in the event that adding the given bundle does not result in an Archetype change . Results are cached in the Archetype Graph to avoid redundant work . if ` intersection ` is false attempting to remove a bundle with components _not_ contained in the current archetype will fail returning None . if ` intersection ` is true components in the bundle but not in the current archetype will be ignored
unsafe fn remove_bundle_from_archetype(
    archetypes: &mut Archetypes,
    storages: &mut Storages,
    components: &mut Components,
    archetype_id: ArchetypeId,
    bundle_info: &BundleInfo,
    intersection: bool,
) -> Option<ArchetypeId> {
    // check the archetype graph to see if the Bundle has been removed from this archetype in the
    // past
    let remove_bundle_result = {
        let current_archetype = &mut archetypes[archetype_id];
        if intersection {
            current_archetype
                .edges()
                .get_remove_bundle_intersection(bundle_info.id)
        } else {
            current_archetype.edges().get_remove_bundle(bundle_info.id)
        }
    };
    let result = if let Some(result) = remove_bundle_result {
        // this Bundle removal result is cached. just return that!
        result
    } else {
        let mut next_table_components;
        let mut next_sparse_set_components;
        let next_table_id;
        {
            let current_archetype = &mut archetypes[archetype_id];
            let mut removed_table_components = Vec::new();
            let mut removed_sparse_set_components = Vec::new();
            for component_id in bundle_info.component_ids.iter().cloned() {
                if current_archetype.contains(component_id) {
                    // SAFE: bundle components were already initialized by bundles.get_info
                    let component_info = components.get_info_unchecked(component_id);
                    match component_info.storage_type() {
                        StorageType::Table => removed_table_components.push(component_id),
                        StorageType::SparseSet => removed_sparse_set_components.push(component_id),
                    }
                } else if !intersection {
                    // a component in the bundle was not present in the entity's archetype, so this
                    // removal is invalid cache the result in the archetype
                    // graph
                    current_archetype
                        .edges_mut()
                        .insert_remove_bundle(bundle_info.id, None);
                    return None;
                }
            }
            // sort removed components so we can do an efficient "sorted remove". archetype
            // components are already sorted
            removed_table_components.sort();
            removed_sparse_set_components.sort();
            next_table_components = current_archetype.table_components().to_vec();
            next_sparse_set_components = current_archetype.sparse_set_components().to_vec();
            sorted_remove(&mut next_table_components, &removed_table_components);
            sorted_remove(
                &mut next_sparse_set_components,
                &removed_sparse_set_components,
            );
            next_table_id = if removed_table_components.is_empty() {
                current_archetype.table_id()
            } else {
                // SAFE: all components in next_table_components exist
                storages
                    .tables
                    .get_id_or_insert(&next_table_components, components)
            };
        }
        let new_archetype_id = archetypes.get_id_or_insert(
            next_table_id,
            next_table_components,
            next_sparse_set_components,
        );
        Some(new_archetype_id)
    };
    let current_archetype = &mut archetypes[archetype_id];
    // cache the result in an edge
    if intersection {
        current_archetype
            .edges_mut()
            .insert_remove_bundle_intersection(bundle_info.id, result);
    } else {
        current_archetype
            .edges_mut()
            .insert_remove_bundle(bundle_info.id, result);
    }
    result
}
unsafe fn remove_bundle_from_archetype ( archetypes : & mut Archetypes , storages : & mut Storages , components : & mut Components , archetype_id : ArchetypeId , bundle_info : & BundleInfo , intersection : bool , ) -> Option < ArchetypeId > { // check the archetype graph to see if the Bundle has been removed from this archetype in the // past let remove_bundle_result = { let current_archetype = & mut archetypes [ archetype_id ] ; if intersection { current_archetype . edges ( ) . get_remove_bundle_intersection ( bundle_info . id ) } else { current_archetype . edges ( ) . get_remove_bundle ( bundle_info . id ) } } ; let result = if let Some ( result ) = remove_bundle_result { // this Bundle removal result is cached. just return that! result } else { let mut next_table_components ; let mut next_sparse_set_components ; let next_table_id ; { let current_archetype = & mut archetypes [ archetype_id ] ; let mut removed_table_components = Vec :: new ( ) ; let mut removed_sparse_set_components = Vec :: new ( ) ; for component_id in bundle_info . component_ids . iter ( ) . cloned ( ) { if current_archetype . contains ( component_id ) { // SAFE: bundle components were already initialized by bundles.get_info let component_info = components . get_info_unchecked ( component_id ) ; match component_info . storage_type ( ) { StorageType :: Table => removed_table_components . push ( component_id ) , StorageType :: SparseSet => removed_sparse_set_components . push ( component_id ) , } } else if ! intersection { // a component in the bundle was not present in the entity's archetype, so this // removal is invalid cache the result in the archetype // graph current_archetype . edges_mut ( ) . insert_remove_bundle ( bundle_info . id , None ) ; return None ; } } // sort removed components so we can do an efficient "sorted remove". archetype // components are already sorted removed_table_components . sort ( ) ; removed_sparse_set_components . sort ( ) ; next_table_components = current_archetype . table_components ( ) . to_vec ( ) ; next_sparse_set_components = current_archetype . sparse_set_components ( ) . to_vec ( ) ; sorted_remove ( & mut next_table_components , & removed_table_components ) ; sorted_remove ( & mut next_sparse_set_components , & removed_sparse_set_components , ) ; next_table_id = if removed_table_components . is_empty ( ) { current_archetype . table_id ( ) } else { // SAFE: all components in next_table_components exist storages . tables . get_id_or_insert ( & next_table_components , components ) } ; } let new_archetype_id = archetypes . get_id_or_insert ( next_table_id , next_table_components , next_sparse_set_components , ) ; Some ( new_archetype_id ) } ; let current_archetype = & mut archetypes [ archetype_id ] ; // cache the result in an edge if intersection { current_archetype . edges_mut ( ) . insert_remove_bundle_intersection ( bundle_info . id , result ) ; } else { current_archetype . edges_mut ( ) . insert_remove_bundle ( bundle_info . id , result ) ; } result }
Removes a bundle from the given archetype and returns the resulting archetype (or None if the
removal was invalid).
Removes a bundle from the given archetype and returns the resulting archetype ( or None if the removal was invalid ) .
archetypes
&mut Archetypes
storages
&mut Storages
components
&mut Components
archetype_id
ArchetypeId
bundle_info
&BundleInfo
intersection
bool
archetypes
&mut Archetypes
storages
&mut Storages
components
&mut Components
archetype_id
ArchetypeId
bundle_info
&BundleInfo
intersection
bool
safety
`archetype_id` must exist and components in `bundle_info` must exist
` archetype_id ` must exist and components in ` bundle_info ` must exist