Skip to content

Commit 32be92b

Browse files
committed
New SystemParams: Archetypes, Components, Entities, Bundles
1 parent 9a39f06 commit 32be92b

File tree

3 files changed

+178
-3
lines changed

3 files changed

+178
-3
lines changed

crates/bevy_ecs/src/core/bundle.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,21 @@ impl BundleInfo {
130130
bundle_component += 1;
131131
});
132132
}
133+
134+
#[inline]
135+
pub fn id(&self) -> BundleId {
136+
self.id
137+
}
138+
139+
#[inline]
140+
pub fn components(&self) -> &[ComponentId] {
141+
&self.component_ids
142+
}
143+
144+
#[inline]
145+
pub fn storage_types(&self) -> &[StorageType] {
146+
&self.storage_types
147+
}
133148
}
134149

135150
#[derive(Default)]

crates/bevy_ecs/src/system/mod.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ pub use system_param::*;
1818
#[cfg(test)]
1919
mod tests {
2020
use crate::{
21-
core::{Added, Changed, Entity, FromWorld, Mutated, Or, With, Without, World},
21+
core::{
22+
Added, Archetypes, Bundles, Changed, Components, Entities, Entity, FromWorld, Mutated,
23+
Or, With, Without, World,
24+
},
2225
schedule::{Schedule, Stage, SystemStage},
2326
system::{IntoSystem, Local, Query, QuerySet, RemovedComponents, Res, ResMut, System},
2427
};
@@ -391,6 +394,50 @@ mod tests {
391394
sys.system().config(|config| config.0 = Some(42)),
392395
);
393396

397+
// ensure the system actually ran
398+
assert_eq!(*world.get_resource::<bool>().unwrap(), true);
399+
}
400+
#[test]
401+
fn world_collections_system() {
402+
let mut world = World::default();
403+
world.insert_resource(false);
404+
world.spawn().insert_bundle((42, true));
405+
fn sys(
406+
archetypes: &Archetypes,
407+
components: &Components,
408+
entities: &Entities,
409+
bundles: &Bundles,
410+
query: Query<Entity, With<i32>>,
411+
mut modified: ResMut<bool>,
412+
) {
413+
assert_eq!(query.iter().count(), 1, "entity exists");
414+
for entity in query.iter() {
415+
let location = entities.get(entity).unwrap();
416+
let archetype = archetypes.get(location.archetype_id).unwrap();
417+
let archetype_components = archetype.components().collect::<Vec<_>>();
418+
let bundle_id = bundles
419+
.get_id(std::any::TypeId::of::<(i32, bool)>())
420+
.expect("Bundle used to spawn entity should exist");
421+
let bundle_info = bundles.get(bundle_id).unwrap();
422+
let mut bundle_components =
423+
bundle_info.components().iter().cloned().collect::<Vec<_>>();
424+
bundle_components.sort();
425+
for component_id in bundle_components.iter() {
426+
assert!(
427+
components.get_info(*component_id).is_some(),
428+
"every bundle component exists in Components"
429+
);
430+
}
431+
assert_eq!(
432+
bundle_components, archetype_components,
433+
"entity's bundle components exactly match entity's archetype components"
434+
);
435+
}
436+
*modified = true;
437+
}
438+
439+
run_system(&mut world, sys.system());
440+
394441
// ensure the system actually ran
395442
assert_eq!(*world.get_resource::<bool>().unwrap(), true);
396443
}

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::{
22
core::{
3-
Archetype, Component, ComponentFlags, ComponentId, Entity, FilterFetch, FilteredAccess,
4-
FilteredAccessSet, FromWorld, Or, QueryState, World, WorldQuery,
3+
Archetype, Archetypes, Bundles, Component, ComponentFlags, ComponentId, Components,
4+
Entities, Entity, FilterFetch, FilteredAccess, FilteredAccessSet, FromWorld, Or,
5+
QueryState, World, WorldQuery,
56
},
67
system::{CommandQueue, Commands, Query, SystemState},
78
};
@@ -567,6 +568,118 @@ impl<'a, T: 'static> SystemParamFetch<'a> for NonSendMutState<T> {
567568

568569
pub struct OrState<T>(T);
569570

571+
impl<'a> SystemParam for &'a Archetypes {
572+
type Fetch = ArchetypesState;
573+
}
574+
575+
pub struct ArchetypesState;
576+
577+
// SAFE: no component value access
578+
unsafe impl SystemParamState for ArchetypesState {
579+
type Config = ();
580+
581+
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
582+
Self
583+
}
584+
}
585+
586+
impl<'a> SystemParamFetch<'a> for ArchetypesState {
587+
type Item = &'a Archetypes;
588+
589+
#[inline]
590+
unsafe fn get_param(
591+
_state: &'a mut Self,
592+
_system_state: &'a SystemState,
593+
world: &'a World,
594+
) -> Option<Self::Item> {
595+
Some(world.archetypes())
596+
}
597+
}
598+
599+
impl<'a> SystemParam for &'a Components {
600+
type Fetch = ComponentsState;
601+
}
602+
603+
pub struct ComponentsState;
604+
605+
// SAFE: no component value access
606+
unsafe impl SystemParamState for ComponentsState {
607+
type Config = ();
608+
609+
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
610+
Self
611+
}
612+
}
613+
614+
impl<'a> SystemParamFetch<'a> for ComponentsState {
615+
type Item = &'a Components;
616+
617+
#[inline]
618+
unsafe fn get_param(
619+
_state: &'a mut Self,
620+
_system_state: &'a SystemState,
621+
world: &'a World,
622+
) -> Option<Self::Item> {
623+
Some(world.components())
624+
}
625+
}
626+
627+
impl<'a> SystemParam for &'a Entities {
628+
type Fetch = EntitiesState;
629+
}
630+
631+
pub struct EntitiesState;
632+
633+
// SAFE: no component value access
634+
unsafe impl SystemParamState for EntitiesState {
635+
type Config = ();
636+
637+
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
638+
Self
639+
}
640+
}
641+
642+
impl<'a> SystemParamFetch<'a> for EntitiesState {
643+
type Item = &'a Entities;
644+
645+
#[inline]
646+
unsafe fn get_param(
647+
_state: &'a mut Self,
648+
_system_state: &'a SystemState,
649+
world: &'a World,
650+
) -> Option<Self::Item> {
651+
Some(world.entities())
652+
}
653+
}
654+
655+
impl<'a> SystemParam for &'a Bundles {
656+
type Fetch = BundlesState;
657+
}
658+
659+
pub struct BundlesState;
660+
661+
// SAFE: no component value access
662+
unsafe impl SystemParamState for BundlesState {
663+
type Config = ();
664+
665+
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
666+
Self
667+
}
668+
}
669+
670+
impl<'a> SystemParamFetch<'a> for BundlesState {
671+
type Item = &'a Bundles;
672+
673+
#[inline]
674+
unsafe fn get_param(
675+
_state: &'a mut Self,
676+
_system_state: &'a SystemState,
677+
world: &'a World,
678+
) -> Option<Self::Item> {
679+
Some(world.bundles())
680+
}
681+
}
682+
570683
macro_rules! impl_system_param_tuple {
571684
($($param: ident),*) => {
572685
impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {

0 commit comments

Comments
 (0)