From f1a03a7a3acc75b390c816febe41219eec8d4feb Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Tue, 28 Apr 2020 13:46:07 -0700 Subject: [PATCH] some system_fn renaming and add system examples --- crates/bevy_app/src/system.rs | 18 +++-- crates/bevy_legion/legion_systems/src/lib.rs | 2 +- .../legion_systems/src/system_fn.rs | 62 ++++++++++++---- examples/spawner.rs | 2 +- examples/systems.rs | 72 ++++++++++++------- src/prelude.rs | 1 - 6 files changed, 111 insertions(+), 46 deletions(-) diff --git a/crates/bevy_app/src/system.rs b/crates/bevy_app/src/system.rs index 257143f7af..af60836cf5 100644 --- a/crates/bevy_app/src/system.rs +++ b/crates/bevy_app/src/system.rs @@ -1,8 +1,8 @@ use legion::{ filter::EntityFilter, prelude::{ - into_resource_system, into_system, IntoQuery, ResourceSet, Resources, Runnable, - Schedulable, World, + into_resource_system, IntoQuery, ResourceSet, Resources, Runnable, + Schedulable, World, into_resource_for_each_system, into_for_each_system, }, query::{DefaultFilter, View}, }; @@ -34,7 +34,17 @@ where } impl System { - pub fn resource_for<'a, Q, F, R, X>(name: &'static str, system: F) -> Self + pub fn for_each<'a, Q, F, R>(name: &'static str, system: F) -> Self + where + Q: IntoQuery + DefaultFilter, + >::Iter: Iterator + 'a, + F: FnMut(Q) + Send + Sync + 'static, + R: EntityFilter + Sync + 'static, + { + into_for_each_system(name, system).into() + } + + pub fn resource_for_each<'a, Q, F, R, X>(name: &'static str, system: F) -> Self where Q: IntoQuery + DefaultFilter, >::Iter: Iterator + 'a, @@ -42,7 +52,7 @@ impl System { R: EntityFilter + Sync + 'static, X: ResourceSet + 'static, { - into_system(name, system).into() + into_resource_for_each_system(name, system).into() } pub fn resource<'a, F, X>(name: &'static str, system: F) -> Self diff --git a/crates/bevy_legion/legion_systems/src/lib.rs b/crates/bevy_legion/legion_systems/src/lib.rs index 134bd051fc..19f8ea5d7e 100644 --- a/crates/bevy_legion/legion_systems/src/lib.rs +++ b/crates/bevy_legion/legion_systems/src/lib.rs @@ -16,6 +16,6 @@ pub mod prelude { resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut}, schedule::{Executor, Runnable, Schedulable, Schedule}, System, SystemBuilder, - into_system, into_resource_system + into_for_each_system, into_resource_system, into_resource_for_each_system, }; } diff --git a/crates/bevy_legion/legion_systems/src/system_fn.rs b/crates/bevy_legion/legion_systems/src/system_fn.rs index 986fa3d3b8..1260d80581 100644 --- a/crates/bevy_legion/legion_systems/src/system_fn.rs +++ b/crates/bevy_legion/legion_systems/src/system_fn.rs @@ -3,17 +3,56 @@ use crate::{ schedule::{ArchetypeAccess, Schedulable}, Access, System, SystemAccess, SystemFnWrapper, SystemQuery, }; +use bit_set::BitSet; use fxhash::FxHashMap; use legion_core::{ - borrow::{AtomicRefCell}, + borrow::AtomicRefCell, filter::EntityFilter, query::{DefaultFilter, IntoQuery, View}, - storage::{ComponentTypeId}, + storage::ComponentTypeId, }; use std::marker::PhantomData; -use bit_set::BitSet; -pub fn into_system<'a, Q, F, R, X>(name: &'static str, mut system: F) -> Box +pub fn into_for_each_system<'a, Q, F, R>(name: &'static str, mut system: F) -> Box +where + Q: IntoQuery + DefaultFilter, + >::Iter: Iterator + 'a, + F: FnMut(Q) + Send + Sync + 'static, + R: EntityFilter + Sync + 'static, +{ + let resource_access: Access = Access::default(); + 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 = SystemFnWrapper( + move |_, world, _, query: &mut SystemQuery::Filter>| { + for components in query.iter_mut(world) { + system(components); + } + }, + PhantomData, + ); + + Box::new(System { + 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_for_each_system<'a, Q, F, R, X>( + name: &'static str, + mut system: F, +) -> Box where Q: IntoQuery + DefaultFilter, >::Iter: Iterator + 'a, @@ -67,10 +106,7 @@ where let component_access: Access = Access::default(); let run_fn = SystemFnWrapper( - move |_, - _, - resources: &mut X, - _| { + move |_, _, resources: &mut X, _| { system(resources); }, PhantomData, @@ -93,8 +129,8 @@ where #[cfg(test)] mod tests { - use super::into_system; use crate::{ + into_resource_for_each_system, resource::{PreparedRead, PreparedWrite, Resources}, }; use legion_core::{ @@ -113,15 +149,13 @@ mod tests { #[test] fn test_system_fn() { - fn read_write_system(_: &mut (), (_x, mut y): (Ref, RefMut)) { - y.0 += 1; - } + fn read_write_system(_: &mut (), (_x, mut y): (Ref, RefMut)) { y.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_system("read_write", read_write_system); + let mut system = into_resource_for_each_system("read_write", read_write_system); system.run(&mut world, &mut resources); } @@ -154,7 +188,7 @@ mod tests { resources.insert(A(0)); resources.insert(B(1)); world.insert((), vec![(X(2), Y(3)), (X(4), Y(5))]); - let mut my_system = into_system("read_resources", my_system); + let mut my_system = into_resource_for_each_system("read_resources", my_system); my_system.run(&mut world, &mut resources); } } diff --git a/examples/spawner.rs b/examples/spawner.rs index 036d143346..940e1c2852 100644 --- a/examples/spawner.rs +++ b/examples/spawner.rs @@ -9,7 +9,7 @@ fn main() { ..Default::default() }) .add_startup_system(setup) - .add_system(System::resource_for("move", move_system)) + .add_system(System::resource_for_each("move", move_system)) .run(); } diff --git a/examples/systems.rs b/examples/systems.rs index 54ac2f452b..6e30206f17 100644 --- a/examples/systems.rs +++ b/examples/systems.rs @@ -1,34 +1,56 @@ -use bevy::{ - input::mouse::{MouseButtonInput, MouseMotion}, - prelude::*, -}; +use bevy::prelude::*; +/// Illustrates the different ways you can declare systems fn main() { App::build() .add_default_plugins() - .add_system_init(mouse_input_system) + .add_event::() + .add_startup_system(setup) + .add_system_init(system_b) + .add_system(System::for_each("system_a", system_a)) .run(); } -/// prints out mouse events as they come in -pub fn mouse_input_system(resources: &mut Resources) -> Box { - let mut mouse_button_input_event_reader = resources.get_event_reader::(); - let mut mouse_motion_event_reader = resources.get_event_reader::(); - SystemBuilder::new("mouse_input") - .read_resource::>() - .read_resource::>() - .build( - move |_command_buffer, - _world, - (mouse_button_input_events, mouse_motion_events), - _queries| { - for event in mouse_button_input_event_reader.iter(&mouse_button_input_events) { - println!("{:?}", event); - } +struct MyEvent(usize); - for event in mouse_motion_event_reader.iter(&mouse_motion_events) { - println!("{:?}", event); - } - }, - ) +// resources +struct A(usize); + +// components +struct X(usize); +struct Y(usize); + +// add our resources and entities +fn setup(world: &mut World, resources: &mut Resources) { + resources.insert(A(0)); + world.insert((), vec![(X(0), Y(1)), (X(2), Y(3))]); +} + +fn system_a((x, y): (Ref, RefMut)) { + +} + +// fn system_a(x: Ref, mut y: RefMut) { + +// } +// fn system_a((my_events, a): &mut (Resource>, Resource), (x, mut y): (Ref, RefMut)) { + +// } + +fn system_b(resources: &mut Resources) -> Box { + let mut my_event_reader = resources.get_event_reader::(); + SystemBuilder::new("example") + .read_resource::>() + .write_resource::() + .with_query(<(Read, Write)>::query()) + .build(move |_command_buffer, world, (my_events, ref mut a), query| { + for event in my_event_reader.iter(&my_events) { + a.0 += event.0; + println!("modified resource A with event: {}", event.0); + } + for (x, mut y) in query.iter_mut(world) { + y.0 += 1; + println!("processed entity: {} {}", x.0, y.0); + } + }) } diff --git a/src/prelude.rs b/src/prelude.rs index bca12901b2..f08cef431a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -55,7 +55,6 @@ pub use legion::{ resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut}, schedule::{Executor, Runnable, Schedulable, Schedule}, SubWorld, SystemBuilder, - into_system, into_resource_system }, world::{Universe, World}, };