diff --git a/crates/bevy_legion/legion_systems/src/lib.rs b/crates/bevy_legion/legion_systems/src/lib.rs index ec10d461c7..e44fb202eb 100644 --- a/crates/bevy_legion/legion_systems/src/lib.rs +++ b/crates/bevy_legion/legion_systems/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(trace_macros)] pub mod resource; pub mod schedule; @@ -14,8 +13,6 @@ pub use system_fn_types::{ResourceMut, Resource}; pub mod prelude { pub use crate::{ bit_set::BitSet, - into_resource_for_each_system, - into_resource_system, // aliased preparedread and preparedwrite used by system_fn resource::{ ResourceSet, Resources, diff --git a/crates/bevy_legion/legion_systems/src/system_fn.rs b/crates/bevy_legion/legion_systems/src/system_fn.rs index 08a3d43b5f..2931ad8aa1 100644 --- a/crates/bevy_legion/legion_systems/src/system_fn.rs +++ b/crates/bevy_legion/legion_systems/src/system_fn.rs @@ -14,174 +14,27 @@ use legion_core::{ }; use std::marker::PhantomData; -pub fn into_resource_for_each_system<'a, Q, F, R, X>( - name: &'static str, - mut system: F, -) -> Box -where - Q: IntoQuery + DefaultFilter, - >::Iter: Iterator + 'a, - F: FnMut(X, Q) + Send + Sync + 'static, - R: EntityFilter + Sync + 'static, - X: ResourceSet + 'static + Clone, -{ - let mut resource_access: Access = Access::default(); - resource_access.reads.extend(X::read_types().iter()); - resource_access.writes.extend(X::write_types().iter()); - - let mut component_access: Access = Access::default(); - component_access.reads.extend(Q::read_types().iter()); - component_access.writes.extend(Q::write_types().iter()); - - let run_fn = FuncSystemFnWrapper( - move |_, world, resources: X, query: &mut SystemQuery::Filter>| { - for components in query.iter_mut(world) { - system(resources.clone(), components); - } - }, - PhantomData, - ); - - Box::new(FuncSystem { - name: name.into(), - queries: AtomicRefCell::new(Q::query()), - access: SystemAccess { - resources: resource_access, - components: component_access, - tags: Access::default(), - }, - archetypes: ArchetypeAccess::Some(BitSet::default()), - _resources: PhantomData::, - command_buffer: FxHashMap::default(), - run_fn: AtomicRefCell::new(run_fn), - }) -} - -pub fn into_resource_system<'a, F, X>(name: &'static str, mut system: F) -> Box -where - F: FnMut(X) + Send + Sync + 'static, - X: ResourceSet + 'static, -{ - let mut resource_access: Access = Access::default(); - resource_access.reads.extend(X::read_types().iter()); - resource_access.writes.extend(X::write_types().iter()); - - let component_access: Access = Access::default(); - let run_fn = FuncSystemFnWrapper( - move |_, _, resources: X, _| { - system(resources); - }, - PhantomData, - ); - - Box::new(FuncSystem { - name: name.into(), - queries: AtomicRefCell::new(()), - access: SystemAccess { - resources: resource_access, - components: component_access, - tags: Access::default(), - }, - archetypes: ArchetypeAccess::Some(BitSet::default()), - _resources: PhantomData::, - command_buffer: FxHashMap::default(), - run_fn: AtomicRefCell::new(run_fn), - }) -} - -pub trait IntoSystem<'a, ResourceArgs, ComponentArgs> -// where -// ComponentArgs: IntoQuery + DefaultFilter, -{ +pub trait IntoSystem<'a, ResourceArgs, ComponentArgs> { fn into_system(self, name: &'static str) -> Box; } -impl< - 'a, - F, - X: ResourceSet + 'static + Clone, - A: for<'b> View<'b> + DefaultFilter + ViewElement, - AF: EntityFilter + Sync + 'static, - B: for<'b> View<'b> + DefaultFilter + ViewElement, - BF: EntityFilter + Sync + 'static, - > IntoSystem<'a, (X,), (A, B)> for F -where - F: FnMut(X, A, B) + Send + Sync + 'static, - >::Iter: Iterator, - >::Iter: Iterator, -{ - fn into_system(mut self, name: &'static str) -> Box { - let mut resource_access: Access = Access::default(); - resource_access.reads.extend(::read_types().iter()); - resource_access.writes.extend(::write_types().iter()); - let mut component_access: Access = Access::default(); - component_access - .reads - .extend(<(A, B) as View>::read_types().iter()); - component_access - .writes - .extend(<(A, B) as View>::write_types().iter()); - - let run_fn = FuncSystemFnWrapper( - move |_, - world, - x: X::PreparedResources, - query: &mut SystemQuery< - (A, B), - EntityFilterTuple< - And<( - ::ArchetypeFilter, - ::ArchetypeFilter, - )>, - And<( - ::ChunksetFilter, - ::ChunksetFilter, - )>, - And<( - ::ChunkFilter, - ::ChunkFilter, - )>, - >, - >| { - for (a, b) in query.iter_mut(world) { - self(x.clone(), a, b); - } - }, - PhantomData, - ); - - Box::new(FuncSystem { - name: name.into(), - queries: AtomicRefCell::new(<(A, B)>::query()), - access: SystemAccess { - resources: resource_access, - components: component_access, - tags: Access::default(), - }, - archetypes: ArchetypeAccess::Some(BitSet::default()), - _resources: PhantomData::, - command_buffer: FxHashMap::default(), - run_fn: AtomicRefCell::new(run_fn), - }) - } -} - macro_rules! impl_system { - (($(($view:ident, $filter:ident, $var:ident)),*)) => { + (($(($resource:ident, $resource_var:ident)),*), ($(($view:ident, $filter:ident, $view_var:ident)),*)) => { impl<'a, Func, + $($resource: ResourceSet + 'static + Clone,)* $($view: for<'b> View<'b> + DefaultFilter + ViewElement, $filter: EntityFilter + Sync + 'static),* - > IntoSystem<'a, (), ($($view,)*)> for Func + > IntoSystem<'a, ($($resource,)*), ($($view,)*)> for Func where - Func: FnMut($($view),*) + Send + Sync + 'static, + Func: FnMut($($resource,)* $($view),*) + Send + Sync + 'static, $(<$view as View<'a>>::Iter: Iterator),* { fn into_system(mut self, name: &'static str) -> Box { - let resource_access: Access = Access::default(); + let resource_access: Access = resource_access!(($($resource),*)); let component_access: Access = component_access!(($($view),*)); - let run_fn = function_wrapper!(self, $($view, $filter, $var),*); + let run_fn = function_wrapper!(self, ($($resource, $resource_var),*), ($($view, $filter, $view_var),*)); Box::new(FuncSystem { name: name.into(), @@ -192,7 +45,7 @@ macro_rules! impl_system { tags: Access::default(), }, archetypes: ArchetypeAccess::Some(BitSet::default()), - _resources: PhantomData::<()>, + _resources: PhantomData::, command_buffer: FxHashMap::default(), run_fn: AtomicRefCell::new(run_fn), }) @@ -202,27 +55,29 @@ macro_rules! impl_system { } macro_rules! function_wrapper { - ($me:ident, ) => { + ($me:ident, ($($resource:ident, $resource_var:ident),*), ($($view:ident, $filter:ident, $view_var:ident),*)) => { FuncSystemFnWrapper( - move |_, _, _, _,| { - $me(); + move |_command_buffer, + _world, + _resources: tuple!($($resource),*), + _query: &mut system_query!($($view, $filter),*) + | { + let tuple!($($resource_var),*) = _resources; + run_function!($me, ($($resource, $resource_var),*), _world, _query, ($($view, $filter, $view_var),*)) }, PhantomData, ) }; - ($me:ident, $($view:ident, $filter:ident, $var:ident),+) => { - FuncSystemFnWrapper( - move |_, - world, - _: (), - query: &mut system_query!($($view, $filter),*) - | { - for tuple!($($var),*) in query.iter_mut(world) { - $me($($var),*); - } - }, - PhantomData, - ) +} + +macro_rules! run_function { + ($me:ident, ($($resource:ident, $resource_var:ident),*), $world:ident, $query:ident, ()) => { + $me($($resource_var),*); + }; + ($me:ident, ($($resource:ident, $resource_var:ident),*), $world:ident, $query:ident, ($($view:ident, $filter:ident, $view_var:ident),+)) => { + for tuple!($($view_var),*) in $query.iter_mut($world) { + $me($($resource_var.clone(),)* $($view_var),*); + } } } @@ -248,7 +103,24 @@ macro_rules! component_access { }} } +macro_rules! resource_access { + (()) => {Access::default()}; + (($($resource:ident),+)) => {{ + let mut component_access: Access = Access::default(); + component_access + .reads + .extend(::read_types().iter()); + component_access + .writes + .extend(::write_types().iter()); + component_access + }} +} + macro_rules! system_query { + () => { + () + }; ($view:ident, $filter:ident) => { SystemQuery< $view, @@ -280,37 +152,68 @@ macro_rules! query { } } +macro_rules! impl_system_variants { + ($(($resource:ident, $resource_var:ident)),*) => { + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ()]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7), (V8, V8F, v8))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7), (V8, V8F, v8), (V9, V9F, v9))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7), (V8, V8F, v8), (V9, V9F, v9), (V10, V10F, v10))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7), (V8, V8F, v8), (V9, V9F, v9), (V10, V10F, v10), (V11, V11F, v11))]; + #[rustfmt::skip] + impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5), (V6, V6F, v6), (V7, V7F, v7), (V8, V8F, v8), (V9, V9F, v9), (V10, V10F, v10), (V11, V11F, v11), (V12, V12F, v12))]; + + } +} + #[rustfmt::skip] -impl_system![()]; +impl_system_variants![]; #[rustfmt::skip] -impl_system![((A, AF, a))]; +impl_system_variants![(R1, r1)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b))]; +impl_system_variants![(R1, r1), (R2, r2)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g), (H, HF, h))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7), (R8, r8)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g), (H, HF, h), (I, IF, i))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7), (R8, r8), (R9, r9)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g), (H, HF, h), (I, IF, i), (J, JF, j))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7), (R8, r8), (R9, r9), (R10, r10)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g), (H, HF, h), (I, IF, i), (J, JF, j), (K, KF, k))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7), (R8, r8), (R9, r9), (R10, r10), (R11, r11)]; #[rustfmt::skip] -impl_system![((A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f), (G, GF, g), (H, HF, h), (I, IF, i), (J, JF, j), (K, KF, k), (L, LF, l))]; +impl_system_variants![(R1, r1), (R2, r2), (R3, r3), (R4, r4), (R5, r5), (R6, r6), (R7, r7), (R8, r8), (R9, r9), (R10, r10), (R11, r11), (R12, r12)]; #[cfg(test)] mod tests { use crate::{ - into_resource_for_each_system, resource::Resources, system_fn_types::{Resource, ResourceMut}, IntoSystem, @@ -382,47 +285,32 @@ mod tests { } #[test] - fn test_system_fn() { - fn read_write_system(_: (), (_x, mut y): (Ref, RefMut)) { y.0 += 1; } + fn test_resource_system_fn() { + fn my_system(mut a: ResourceMut, x: Ref, mut y: RefMut) { + assert_eq!(*a, A(1)); + // assert_eq!(**b, B(0)); + if a.0 == 0 { + assert_eq!(*x, X(2)); + assert_eq!(*y, Y(3)); + } else if a.0 == 1 { + assert_eq!(*x, X(4)); + assert_eq!(*y, Y(5)); + y.0 += 1; + assert_eq!(*y, Y(6)); + } else { + panic!("unexpected value"); + } + + a.0 += 1; + } let mut world = World::new(); let mut resources = Resources::default(); - world.insert((), vec![(X(1), Y(1)), (X(2), Y(2))]); - let mut system = into_resource_for_each_system("read_write", read_write_system); - system.run(&mut world, &mut resources); - } - - #[test] - fn test_resource_system_fn() { - // fn my_system( - // (a,): (Resource,), - // (x, mut y): (Ref, RefMut), - // ) { - // assert_eq!(*a, A(1)); - // // assert_eq!(**b, B(0)); - // if a.0 == 0 { - // assert_eq!(*x, X(2)); - // assert_eq!(*y, Y(3)); - // } else if a.0 == 1 { - // assert_eq!(*x, X(4)); - // assert_eq!(*y, Y(5)); - // y.0 += 1; - // assert_eq!(*y, Y(6)); - // } else { - // panic!("unexpected value"); - // } - - // // a.0 += 1; - // } - - // let mut world = World::new(); - // let mut resources = Resources::default(); - - // resources.insert(A(0)); - // resources.insert(B(1)); - // world.insert((), vec![(X(2), Y(3)), (X(4), Y(5))]); - // let mut my_system = into_resource_for_each_system("read_resources", my_system); - // my_system.run(&mut world, &mut resources); + resources.insert(A(0)); + resources.insert(B(1)); + world.insert((), vec![(X(2), Y(3)), (X(4), Y(5))]); + let mut my_system = my_system.into_system("my_system"); + my_system.run(&mut world, &mut resources); } } diff --git a/examples/event.rs b/examples/event.rs index 0ac96034fc..c2e3eae546 100644 --- a/examples/event.rs +++ b/examples/event.rs @@ -6,8 +6,8 @@ fn main() { .add_event::() .add_resource(EventTriggerState::default()) .add_resource_init::() - .add_system(System::resource("event_trigger", event_trigger_system)) - .add_system(System::resource("event_listener", event_listener_system)) + .add_system(event_trigger_system.into_system("event_trigger")) + .add_system(event_listener_system.into_system("event_listener")) .run(); } @@ -22,11 +22,9 @@ struct EventTriggerState { // sends MyEvent every second fn event_trigger_system( - (state, my_events, time): &mut ( - ResourceMut, - ResourceMut>, - Resource