@@ -12,7 +12,8 @@ use crate::{
1212 bundle:: { Bundle , BundleInserter , BundleSpawner , Bundles } ,
1313 change_detection:: { MutUntyped , Ticks } ,
1414 component:: {
15- Component , ComponentDescriptor , ComponentId , ComponentTicks , Components , StorageType ,
15+ Component , ComponentDescriptor , ComponentId , ComponentInfo , ComponentTicks , Components ,
16+ StorageType ,
1617 } ,
1718 entity:: { AllocAtWithoutReplacement , Entities , Entity } ,
1819 query:: { QueryState , WorldQuery } ,
@@ -280,6 +281,30 @@ impl World {
280281 . unwrap_or_else ( || panic ! ( "Entity {:?} does not exist" , entity) )
281282 }
282283
284+ /// Returns the components of an [`Entity`](crate::entity::Entity) through [`ComponentInfo`](crate::component::ComponentInfo).
285+ #[ inline]
286+ pub fn inspect_entity ( & self , entity : Entity ) -> Vec < & ComponentInfo > {
287+ let entity_location = self
288+ . entities ( )
289+ . get ( entity)
290+ . unwrap_or_else ( || panic ! ( "Entity {:?} does not exist" , entity) ) ;
291+
292+ let archetype = self
293+ . archetypes ( )
294+ . get ( entity_location. archetype_id )
295+ . unwrap_or_else ( || {
296+ panic ! (
297+ "Archetype {:?} does not exist" ,
298+ entity_location. archetype_id
299+ )
300+ } ) ;
301+
302+ archetype
303+ . components ( )
304+ . filter_map ( |id| self . components ( ) . get_info ( id) )
305+ . collect ( )
306+ }
307+
283308 /// Returns an [`EntityMut`] for the given `entity` (if it exists) or spawns one if it doesn't exist.
284309 /// This will return [`None`] if the `entity` exists with a different generation.
285310 ///
@@ -1542,11 +1567,13 @@ mod tests {
15421567 use super :: World ;
15431568 use crate :: {
15441569 change_detection:: DetectChanges ,
1545- component:: { ComponentDescriptor , ComponentId , StorageType } ,
1570+ component:: { ComponentDescriptor , ComponentId , ComponentInfo , StorageType } ,
15461571 ptr:: OwningPtr ,
15471572 } ;
15481573 use bevy_ecs_macros:: Component ;
1574+ use bevy_utils:: HashSet ;
15491575 use std:: {
1576+ any:: TypeId ,
15501577 panic,
15511578 sync:: {
15521579 atomic:: { AtomicBool , AtomicU32 , Ordering } ,
@@ -1762,4 +1789,64 @@ mod tests {
17621789 world. insert_resource_by_id ( invalid_component_id, ptr) ;
17631790 } ) ;
17641791 }
1792+
1793+ #[ derive( Component ) ]
1794+ struct Foo ;
1795+
1796+ #[ derive( Component ) ]
1797+ struct Bar ;
1798+
1799+ #[ derive( Component ) ]
1800+ struct Baz ;
1801+
1802+ #[ test]
1803+ fn inspect_entity_components ( ) {
1804+ let mut world = World :: new ( ) ;
1805+ let ent0 = world. spawn ( ) . insert_bundle ( ( Foo , Bar , Baz ) ) . id ( ) ;
1806+ let ent1 = world. spawn ( ) . insert_bundle ( ( Foo , Bar ) ) . id ( ) ;
1807+ let ent2 = world. spawn ( ) . insert_bundle ( ( Bar , Baz ) ) . id ( ) ;
1808+ let ent3 = world. spawn ( ) . insert_bundle ( ( Foo , Baz ) ) . id ( ) ;
1809+ let ent4 = world. spawn ( ) . insert_bundle ( ( Foo , ) ) . id ( ) ;
1810+ let ent5 = world. spawn ( ) . insert_bundle ( ( Bar , ) ) . id ( ) ;
1811+ let ent6 = world. spawn ( ) . insert_bundle ( ( Baz , ) ) . id ( ) ;
1812+
1813+ fn to_type_ids ( component_infos : Vec < & ComponentInfo > ) -> HashSet < Option < TypeId > > {
1814+ component_infos
1815+ . into_iter ( )
1816+ . map ( |component_info| component_info. type_id ( ) )
1817+ . collect ( )
1818+ }
1819+
1820+ let foo_id = TypeId :: of :: < Foo > ( ) ;
1821+ let bar_id = TypeId :: of :: < Bar > ( ) ;
1822+ let baz_id = TypeId :: of :: < Baz > ( ) ;
1823+ assert_eq ! (
1824+ to_type_ids( world. inspect_entity( ent0) ) ,
1825+ [ Some ( foo_id) , Some ( bar_id) , Some ( baz_id) ] . into( )
1826+ ) ;
1827+ assert_eq ! (
1828+ to_type_ids( world. inspect_entity( ent1) ) ,
1829+ [ Some ( foo_id) , Some ( bar_id) ] . into( )
1830+ ) ;
1831+ assert_eq ! (
1832+ to_type_ids( world. inspect_entity( ent2) ) ,
1833+ [ Some ( bar_id) , Some ( baz_id) ] . into( )
1834+ ) ;
1835+ assert_eq ! (
1836+ to_type_ids( world. inspect_entity( ent3) ) ,
1837+ [ Some ( foo_id) , Some ( baz_id) ] . into( )
1838+ ) ;
1839+ assert_eq ! (
1840+ to_type_ids( world. inspect_entity( ent4) ) ,
1841+ [ Some ( foo_id) ] . into( )
1842+ ) ;
1843+ assert_eq ! (
1844+ to_type_ids( world. inspect_entity( ent5) ) ,
1845+ [ Some ( bar_id) ] . into( )
1846+ ) ;
1847+ assert_eq ! (
1848+ to_type_ids( world. inspect_entity( ent6) ) ,
1849+ [ Some ( baz_id) ] . into( )
1850+ ) ;
1851+ }
17651852}
0 commit comments