Add command encoder system variants

This commit is contained in:
Carter Anderson 2020-04-30 10:42:22 -07:00
parent c04b4a6c0b
commit 2047f9c0d9
4 changed files with 106 additions and 72 deletions

View File

@ -11,31 +11,31 @@ use legion_core::{
filter::{And, EntityFilter, EntityFilterTuple}, filter::{And, EntityFilter, EntityFilterTuple},
query::{DefaultFilter, IntoQuery, View, ViewElement}, query::{DefaultFilter, IntoQuery, View, ViewElement},
storage::ComponentTypeId, storage::ComponentTypeId,
command::CommandBuffer,
}; };
use std::marker::PhantomData; use std::marker::PhantomData;
pub trait IntoSystem<'a, ResourceArgs, ComponentArgs> { pub trait IntoSystem<'a, CommandBuffer, ResourceArgs, ComponentArgs> {
fn into_system(self, name: &'static str) -> Box<dyn Schedulable>; fn into_system(self, name: &'static str) -> Box<dyn Schedulable>;
} }
macro_rules! impl_system { macro_rules! impl_system {
(($(($resource:ident, $resource_var:ident)),*), ($(($view:ident, $filter:ident, $view_var:ident)),*)) => { (($($command_buffer:ident)*), ($(($resource:ident, $resource_var:ident)),*), ($(($view:ident, $filter:ident, $view_var:ident)),*)) => {
impl<'a, impl<'a,
Func, Func,
$($resource: ResourceSet<PreparedResources = $resource> + 'static + Clone,)* $($resource: ResourceSet<PreparedResources = $resource> + 'static + Clone,)*
$($view: for<'b> View<'b> + DefaultFilter<Filter = $filter> + ViewElement, $($view: for<'b> View<'b> + DefaultFilter<Filter = $filter> + ViewElement,
$filter: EntityFilter + Sync + 'static),* $filter: EntityFilter + Sync + 'static),*
> IntoSystem<'a, ($($resource,)*), ($($view,)*)> for Func > IntoSystem<'a, tuple!($($command_buffer)*), ($($resource,)*), ($($view,)*)> for Func
where where
Func: FnMut($($resource,)* $($view),*) + Send + Sync + 'static, Func: FnMut($(&mut $command_buffer,)* $($resource,)* $($view),*) + Send + Sync + 'static,
$(<$view as View<'a>>::Iter: Iterator<Item = $view>),* $(<$view as View<'a>>::Iter: Iterator<Item = $view>),*
{ {
fn into_system(mut self, name: &'static str) -> Box<dyn Schedulable> { fn into_system(mut self, name: &'static str) -> Box<dyn Schedulable> {
let resource_access: Access<ResourceTypeId> = resource_access!(($($resource),*)); let resource_access: Access<ResourceTypeId> = resource_access!(($($resource),*));
let component_access: Access<ComponentTypeId> = component_access!(($($view),*)); let component_access: Access<ComponentTypeId> = component_access!(($($view),*));
let run_fn = function_wrapper!(self, ($($resource, $resource_var),*), ($($view, $filter, $view_var),*)); let run_fn = function_wrapper!(self, ($($command_buffer)*), ($($resource, $resource_var),*), ($($view, $filter, $view_var),*));
Box::new(FuncSystem { Box::new(FuncSystem {
name: name.into(), name: name.into(),
queries: AtomicRefCell::new(query!($($view),*)), queries: AtomicRefCell::new(query!($($view),*)),
@ -55,7 +55,7 @@ macro_rules! impl_system {
} }
macro_rules! function_wrapper { macro_rules! function_wrapper {
($me:ident, ($($resource:ident, $resource_var:ident),*), ($($view:ident, $filter:ident, $view_var:ident),*)) => { ($me:ident, ($($command_buffer:ident)*), ($($resource:ident, $resource_var:ident),*), ($($view:ident, $filter:ident, $view_var:ident),*)) => {
FuncSystemFnWrapper( FuncSystemFnWrapper(
move |_command_buffer, move |_command_buffer,
_world, _world,
@ -63,7 +63,7 @@ macro_rules! function_wrapper {
_query: &mut system_query!($($view, $filter),*) _query: &mut system_query!($($view, $filter),*)
| { | {
let tuple!($($resource_var),*) = _resources; let tuple!($($resource_var),*) = _resources;
run_function!($me, ($($resource, $resource_var),*), _world, _query, ($($view, $filter, $view_var),*)) run_function!($me, ($(_command_buffer, $command_buffer)*), ($($resource, $resource_var),*), _world, _query, ($($view, $filter, $view_var),*))
}, },
PhantomData, PhantomData,
) )
@ -71,12 +71,12 @@ macro_rules! function_wrapper {
} }
macro_rules! run_function { macro_rules! run_function {
($me:ident, ($($resource:ident, $resource_var:ident),*), $world:ident, $query:ident, ()) => { ($me:ident, ($($command_buffer_var:ident, $command_buffer:ident)*), ($($resource:ident, $resource_var:ident),*), $world:ident, $query:ident, ()) => {
$me($($resource_var),*); $me($($command_buffer_var,)*$($resource_var),*);
}; };
($me:ident, ($($resource:ident, $resource_var:ident),*), $world:ident, $query:ident, ($($view:ident, $filter:ident, $view_var:ident),+)) => { ($me:ident, ($($command_buffer_var:ident, $command_buffer: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) { for tuple!($($view_var),*) in $query.iter_mut($world) {
$me($($resource_var.clone(),)* $($view_var),*); $me($($command_buffer_var,)*$($resource_var.clone(),)* $($view_var),*);
} }
} }
} }
@ -155,31 +155,58 @@ macro_rules! query {
macro_rules! impl_system_variants { macro_rules! impl_system_variants {
($(($resource:ident, $resource_var:ident)),*) => { ($(($resource:ident, $resource_var:ident)),*) => {
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ()]; impl_system![(), ($(($resource, $resource_var)),*), ()];
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1))]; impl_system![(), ($(($resource, $resource_var)),*), ((V1, V1F, v1))];
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2))]; impl_system![(), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2))];
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3))]; impl_system![(), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3))];
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4))]; impl_system![(), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4))];
#[rustfmt::skip] #[rustfmt::skip]
impl_system![($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5))]; impl_system![(), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5))];
#[rustfmt::skip] #[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))]; 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] #[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))]; 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] #[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))]; 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] #[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))]; 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] #[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))]; 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] #[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))]; 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] #[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))]; 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![(CommandBuffer), ($(($resource, $resource_var)),*), ()];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($resource, $resource_var)),*), ((V1, V1F, v1))];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2))];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3))];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4))];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($resource, $resource_var)),*), ((V1, V1F, v1), (V2, V2F, v2), (V3, V3F, v3), (V4, V4F, v4), (V5, V5F, v5))];
#[rustfmt::skip]
impl_system![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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![(CommandBuffer), ($(($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))];
} }
} }
@ -220,7 +247,7 @@ mod tests {
}; };
use legion_core::{ use legion_core::{
borrow::{Ref, RefMut}, borrow::{Ref, RefMut},
world::World, world::World, command::CommandBuffer,
}; };
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
@ -281,17 +308,25 @@ mod tests {
} }
let mut system = resource_system_mut.into_system("hi"); let mut system = resource_system_mut.into_system("hi");
system.run(&mut world, &mut resources); system.run(&mut world, &mut resources);
fn command_buffer_system(command_buffer: &mut CommandBuffer, mut a: ResourceMut<A>) {
a.0 += 1;
command_buffer.insert((), vec![(X(1), Y(1)), (X(2), Y(2))]);
println!("{}", a.0);
}
let mut system = command_buffer_system.into_system("hi");
system.run(&mut world, &mut resources);
} }
#[test] #[test]
fn test_resource_system_fn() { fn test_resource_system_fn() {
fn my_system(mut a: ResourceMut<A>, x: Ref<X>, mut y: RefMut<Y>) { fn my_system(mut a: ResourceMut<A>, x: Ref<X>, mut y: RefMut<Y>) {
assert_eq!(*a, A(1));
// assert_eq!(**b, B(0));
if a.0 == 0 { if a.0 == 0 {
assert_eq!(*a, A(0));
assert_eq!(*x, X(2)); assert_eq!(*x, X(2));
assert_eq!(*y, Y(3)); assert_eq!(*y, Y(3));
} else if a.0 == 1 { } else if a.0 == 1 {
assert_eq!(*a, A(1));
assert_eq!(*x, X(4)); assert_eq!(*x, X(4));
assert_eq!(*y, Y(5)); assert_eq!(*y, Y(5));
y.0 += 1; y.0 += 1;

View File

@ -17,7 +17,7 @@ fn main() {
.add_plugin(ScheduleRunnerPlugin { .add_plugin(ScheduleRunnerPlugin {
run_mode: RunMode::Once, run_mode: RunMode::Once,
}) })
.add_system(hello_world_system()) .add_system(hello_world_system.into_system("hello"))
.run(); .run();
// this app loops forever at 60 fps // this app loops forever at 60 fps
@ -27,12 +27,10 @@ fn main() {
wait: Some(Duration::from_secs_f64(1.0 / 60.0)), wait: Some(Duration::from_secs_f64(1.0 / 60.0)),
}, },
}) })
.add_system(hello_world_system()) .add_system(hello_world_system.into_system("hello"))
.run(); .run();
} }
pub fn hello_world_system() -> Box<dyn Schedulable> { pub fn hello_world_system() {
SystemBuilder::new("hello_world").build(move |_, _, _, _| { println!("hello world");
println!("hello world");
})
} }

View File

@ -3,8 +3,10 @@ use bevy::prelude::*;
fn main() { fn main() {
App::build() App::build()
.add_default_plugins() .add_default_plugins()
.add_system(|_: &mut World, _: &mut Resources| { .add_system(hello_world_system.into_system("hello"))
println!("hello world");
})
.run(); .run();
} }
pub fn hello_world_system() {
println!("hello world");
}

View File

@ -3,46 +3,45 @@ use bevy::prelude::*;
fn main() { fn main() {
App::build() App::build()
.add_default_plugins() .add_default_plugins()
.add_startup_system(startup_system()) .add_startup_system(startup_system.into_system("startup"))
.run(); .run();
} }
/// Set up a simple scene using a "startup system". /// Set up a simple scene using a "startup system".
/// Startup systems are run exactly once when the app starts up. /// Startup systems are run exactly once when the app starts up.
/// They run right before "normal" systems run. /// They run right before "normal" systems run.
pub fn startup_system() -> Box<dyn Schedulable> { fn startup_system(
SystemBuilder::new("startup") command_buffer: &mut CommandBuffer,
.write_resource::<AssetStorage<Mesh>>() mut meshes: ResourceMut<AssetStorage<Mesh>>,
.write_resource::<AssetStorage<StandardMaterial>>() mut materials: ResourceMut<AssetStorage<StandardMaterial>>,
.build(move |command_buffer, _, (meshes, materials), _| { ) {
let cube_handle = meshes.add(Mesh::from(shape::Cube)); let cube_handle = meshes.add(Mesh::from(shape::Cube));
let cube_material_handle = materials.add(StandardMaterial { let cube_material_handle = materials.add(StandardMaterial {
albedo: Color::rgb(0.5, 0.4, 0.3), albedo: Color::rgb(0.5, 0.4, 0.3),
..Default::default() ..Default::default()
}); });
command_buffer command_buffer
.build() .build()
// cube // cube
.add_entity(MeshEntity { .add_entity(MeshEntity {
mesh: cube_handle, mesh: cube_handle,
material: cube_material_handle, material: cube_material_handle,
translation: Translation::new(0.0, 0.0, 0.0), translation: Translation::new(0.0, 0.0, 0.0),
..Default::default() ..Default::default()
})
// light
.add_entity(LightEntity {
translation: Translation::new(4.0, -4.0, 5.0),
..Default::default()
})
// camera
.add_entity(CameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
)),
..Default::default()
});
}) })
} // light
.add_entity(LightEntity {
translation: Translation::new(4.0, -4.0, 5.0),
..Default::default()
})
// camera
.add_entity(CameraEntity {
local_to_world: LocalToWorld(Mat4::look_at_rh(
Vec3::new(3.0, 8.0, 5.0),
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, 1.0),
)),
..Default::default()
});
}