@@ -12,7 +12,8 @@ use crate::{
12
12
bundle:: { Bundle , BundleInserter , BundleSpawner , Bundles } ,
13
13
change_detection:: { MutUntyped , Ticks } ,
14
14
component:: {
15
- Component , ComponentDescriptor , ComponentId , ComponentTicks , Components , StorageType ,
15
+ Component , ComponentDescriptor , ComponentId , ComponentInfo , ComponentTicks , Components ,
16
+ StorageType ,
16
17
} ,
17
18
entity:: { AllocAtWithoutReplacement , Entities , Entity } ,
18
19
query:: { QueryState , WorldQuery } ,
@@ -280,6 +281,30 @@ impl World {
280
281
. unwrap_or_else ( || panic ! ( "Entity {:?} does not exist" , entity) )
281
282
}
282
283
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
+
283
308
/// Returns an [`EntityMut`] for the given `entity` (if it exists) or spawns one if it doesn't exist.
284
309
/// This will return [`None`] if the `entity` exists with a different generation.
285
310
///
@@ -1542,11 +1567,13 @@ mod tests {
1542
1567
use super :: World ;
1543
1568
use crate :: {
1544
1569
change_detection:: DetectChanges ,
1545
- component:: { ComponentDescriptor , ComponentId , StorageType } ,
1570
+ component:: { ComponentDescriptor , ComponentId , ComponentInfo , StorageType } ,
1546
1571
ptr:: OwningPtr ,
1547
1572
} ;
1548
1573
use bevy_ecs_macros:: Component ;
1574
+ use bevy_utils:: HashSet ;
1549
1575
use std:: {
1576
+ any:: TypeId ,
1550
1577
panic,
1551
1578
sync:: {
1552
1579
atomic:: { AtomicBool , AtomicU32 , Ordering } ,
@@ -1762,4 +1789,64 @@ mod tests {
1762
1789
world. insert_resource_by_id ( invalid_component_id, ptr) ;
1763
1790
} ) ;
1764
1791
}
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
+ }
1765
1852
}
0 commit comments