add len, is_empty, iter method on SparseSets, make SparseSets inspect… (#7638)
…able like Table. Rename clear to clear_entities to clarify that metadata keeps, only value cleared # Objective - Provide some inspectability for SparseSets. ## Solution - `Tables` has these three methods, len, is_empty and iter too. Add these methods to `SparseSets`, so user can print the shape of storage. --- ## Changelog > This section is optional. If this was a trivial fix, or has no externally-visible impact, you can delete this section. - Add `len`, `is_empty`, `iter` methods on SparseSets. - Rename `clear` to `clear_entities` to clarify its purpose. - Add `new_for_test` on `ComponentInfo` to make test code easy. - Add test case covering new methods. ## Migration Guide > This section is optional. If there are no breaking changes, you can delete this section. - Simply adding new functionality is not a breaking change.
This commit is contained in:
		
							parent
							
								
									e392e99f7e
								
							
						
					
					
						commit
						1dc713b605
					
				@ -239,7 +239,8 @@ impl ComponentInfo {
 | 
			
		||||
        self.descriptor.is_send_and_sync
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn new(id: ComponentId, descriptor: ComponentDescriptor) -> Self {
 | 
			
		||||
    /// Create a new [`ComponentInfo`].
 | 
			
		||||
    pub(crate) fn new(id: ComponentId, descriptor: ComponentDescriptor) -> Self {
 | 
			
		||||
        ComponentInfo { id, descriptor }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -497,7 +497,35 @@ pub struct SparseSets {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SparseSets {
 | 
			
		||||
    pub fn get_or_insert(&mut self, component_info: &ComponentInfo) -> &mut ComponentSparseSet {
 | 
			
		||||
    /// Returns the number of [`ComponentSparseSet`]s this collection contains.
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn len(&self) -> usize {
 | 
			
		||||
        self.sets.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns true if this collection contains no [`ComponentSparseSet`]s.
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn is_empty(&self) -> bool {
 | 
			
		||||
        self.sets.is_empty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// An Iterator visiting all ([`ComponentId`], [`ComponentSparseSet`]) pairs.
 | 
			
		||||
    /// NOTE: Order is not guaranteed.
 | 
			
		||||
    pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
 | 
			
		||||
        self.sets.iter().map(|(id, data)| (*id, data))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Gets a reference to the [`ComponentSparseSet`] of a [`ComponentId`].
 | 
			
		||||
    pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
 | 
			
		||||
        self.sets.get(component_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Gets a mutable reference of [`ComponentSparseSet`] of a [`ComponentInfo`].
 | 
			
		||||
    /// Create a new [`ComponentSparseSet`] if not exists.
 | 
			
		||||
    pub(crate) fn get_or_insert(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        component_info: &ComponentInfo,
 | 
			
		||||
    ) -> &mut ComponentSparseSet {
 | 
			
		||||
        if !self.sets.contains(component_info.id()) {
 | 
			
		||||
            self.sets.insert(
 | 
			
		||||
                component_info.id(),
 | 
			
		||||
@ -508,15 +536,13 @@ impl SparseSets {
 | 
			
		||||
        self.sets.get_mut(component_info.id()).unwrap()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
 | 
			
		||||
        self.sets.get(component_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
 | 
			
		||||
    /// Gets a mutable reference to the [`ComponentSparseSet`] of a [`ComponentId`].
 | 
			
		||||
    pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
 | 
			
		||||
        self.sets.get_mut(component_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn clear(&mut self) {
 | 
			
		||||
    /// Clear entities stored in each [`ComponentSparseSet`]
 | 
			
		||||
    pub(crate) fn clear_entities(&mut self) {
 | 
			
		||||
        for set in self.sets.values_mut() {
 | 
			
		||||
            set.clear();
 | 
			
		||||
        }
 | 
			
		||||
@ -531,7 +557,13 @@ impl SparseSets {
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use crate::{entity::Entity, storage::SparseSet};
 | 
			
		||||
    use super::SparseSets;
 | 
			
		||||
    use crate::{
 | 
			
		||||
        self as bevy_ecs,
 | 
			
		||||
        component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
 | 
			
		||||
        entity::Entity,
 | 
			
		||||
        storage::SparseSet,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Eq, PartialEq)]
 | 
			
		||||
    struct Foo(usize);
 | 
			
		||||
@ -584,4 +616,42 @@ mod tests {
 | 
			
		||||
        *set.get_mut(e1).unwrap() = Foo(11);
 | 
			
		||||
        assert_eq!(set.get(e1), Some(&Foo(11)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn sparse_sets() {
 | 
			
		||||
        let mut sets = SparseSets::default();
 | 
			
		||||
 | 
			
		||||
        #[derive(Component, Default, Debug)]
 | 
			
		||||
        struct TestComponent1;
 | 
			
		||||
 | 
			
		||||
        #[derive(Component, Default, Debug)]
 | 
			
		||||
        struct TestComponent2;
 | 
			
		||||
 | 
			
		||||
        assert_eq!(sets.len(), 0);
 | 
			
		||||
        assert!(sets.is_empty());
 | 
			
		||||
 | 
			
		||||
        init_component::<TestComponent1>(&mut sets, 1);
 | 
			
		||||
        assert_eq!(sets.len(), 1);
 | 
			
		||||
 | 
			
		||||
        init_component::<TestComponent2>(&mut sets, 2);
 | 
			
		||||
        assert_eq!(sets.len(), 2);
 | 
			
		||||
 | 
			
		||||
        // check its shape by iter
 | 
			
		||||
        let mut collected_sets = sets
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|(id, set)| (id, set.len()))
 | 
			
		||||
            .collect::<Vec<_>>();
 | 
			
		||||
        collected_sets.sort();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            collected_sets,
 | 
			
		||||
            vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        fn init_component<T: Component>(sets: &mut SparseSets, id: usize) {
 | 
			
		||||
            let descriptor = ComponentDescriptor::new::<TestComponent1>();
 | 
			
		||||
            let id = ComponentId::new(id);
 | 
			
		||||
            let info = ComponentInfo::new(id, descriptor);
 | 
			
		||||
            sets.get_or_insert(&info);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -654,11 +654,13 @@ pub(crate) struct TableMoveResult {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Tables {
 | 
			
		||||
    /// Returns the number of [`Table`]s this collection contains
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn len(&self) -> usize {
 | 
			
		||||
        self.tables.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns true if this collection contains no [`Table`]s
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn is_empty(&self) -> bool {
 | 
			
		||||
        self.tables.is_empty()
 | 
			
		||||
 | 
			
		||||
@ -1538,7 +1538,7 @@ impl World {
 | 
			
		||||
    /// Despawns all entities in this [`World`].
 | 
			
		||||
    pub fn clear_entities(&mut self) {
 | 
			
		||||
        self.storages.tables.clear();
 | 
			
		||||
        self.storages.sparse_sets.clear();
 | 
			
		||||
        self.storages.sparse_sets.clear_entities();
 | 
			
		||||
        self.archetypes.clear_entities();
 | 
			
		||||
        self.entities.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user