Implement IntoSystem trait for flat functions using macros
This commit is contained in:
parent
f1a03a7a3a
commit
9230c370ba
@ -2,7 +2,7 @@ use legion::{
|
|||||||
filter::EntityFilter,
|
filter::EntityFilter,
|
||||||
prelude::{
|
prelude::{
|
||||||
into_resource_system, IntoQuery, ResourceSet, Resources, Runnable,
|
into_resource_system, IntoQuery, ResourceSet, Resources, Runnable,
|
||||||
Schedulable, World, into_resource_for_each_system, into_for_each_system,
|
Schedulable, World, into_resource_for_each_system,
|
||||||
},
|
},
|
||||||
query::{DefaultFilter, View},
|
query::{DefaultFilter, View},
|
||||||
};
|
};
|
||||||
@ -34,16 +34,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl System {
|
impl System {
|
||||||
pub fn for_each<'a, Q, F, R>(name: &'static str, system: F) -> Self
|
|
||||||
where
|
|
||||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
|
||||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + '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
|
pub fn resource_for_each<'a, Q, F, R, X>(name: &'static str, system: F) -> Self
|
||||||
where
|
where
|
||||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
Q: IntoQuery + DefaultFilter<Filter = R>,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![feature(trace_macros)]
|
||||||
pub mod resource;
|
pub mod resource;
|
||||||
pub mod schedule;
|
pub mod schedule;
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ pub mod prelude {
|
|||||||
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
|
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
|
||||||
schedule::{Executor, Runnable, Schedulable, Schedule},
|
schedule::{Executor, Runnable, Schedulable, Schedule},
|
||||||
System, SystemBuilder,
|
System, SystemBuilder,
|
||||||
into_for_each_system, into_resource_system, into_resource_for_each_system,
|
into_resource_system, into_resource_for_each_system,
|
||||||
|
IntoSystem
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
resource::{ResourceSet, ResourceTypeId},
|
resource::{PreparedRead, Resource, ResourceSet, ResourceTypeId},
|
||||||
schedule::{ArchetypeAccess, Schedulable},
|
schedule::{ArchetypeAccess, Schedulable},
|
||||||
Access, System, SystemAccess, SystemFnWrapper, SystemQuery,
|
Access, System, SystemAccess, SystemFnWrapper, SystemQuery,
|
||||||
};
|
};
|
||||||
@ -7,47 +7,12 @@ use bit_set::BitSet;
|
|||||||
use fxhash::FxHashMap;
|
use fxhash::FxHashMap;
|
||||||
use legion_core::{
|
use legion_core::{
|
||||||
borrow::AtomicRefCell,
|
borrow::AtomicRefCell,
|
||||||
filter::EntityFilter,
|
filter::{And, EntityFilter, EntityFilterTuple},
|
||||||
query::{DefaultFilter, IntoQuery, View},
|
query::{DefaultFilter, IntoQuery, View, ViewElement},
|
||||||
storage::ComponentTypeId,
|
storage::ComponentTypeId,
|
||||||
};
|
};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub fn into_for_each_system<'a, Q, F, R>(name: &'static str, mut system: F) -> Box<dyn Schedulable>
|
|
||||||
where
|
|
||||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
|
||||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
|
||||||
F: FnMut(Q) + Send + Sync + 'static,
|
|
||||||
R: EntityFilter + Sync + 'static,
|
|
||||||
{
|
|
||||||
let resource_access: Access<ResourceTypeId> = Access::default();
|
|
||||||
let mut component_access: Access<ComponentTypeId> = 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<Q, <Q as DefaultFilter>::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>(
|
pub fn into_resource_for_each_system<'a, Q, F, R, X>(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
@ -127,11 +92,274 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IntoSystem<'a, ResourceArgs, ComponentArgs>
|
||||||
|
where
|
||||||
|
ComponentArgs: IntoQuery + DefaultFilter,
|
||||||
|
{
|
||||||
|
fn into_system(self, name: &'static str) -> Box<dyn Schedulable>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl<F, X: Resource + Send + Sync + 'static, A: Component, B: Component> IntoSystem<(X,), (A, B)> for F
|
||||||
|
// where
|
||||||
|
// F: for<'a> FnMut(&X, Ref<'a, A>, Ref<'a, B>) + Send + Sync + 'static,
|
||||||
|
// {
|
||||||
|
// fn into_system(mut self, name: &'static str) -> Box<dyn Schedulable> {
|
||||||
|
// let mut resource_access: Access<ResourceTypeId> = Access::default();
|
||||||
|
// resource_access
|
||||||
|
// .reads
|
||||||
|
// .extend(<PreparedRead<X>>::read_types().iter());
|
||||||
|
// resource_access
|
||||||
|
// .writes
|
||||||
|
// .extend(<PreparedRead<X>>::write_types().iter());
|
||||||
|
// let mut component_access: Access<ComponentTypeId> = Access::default();
|
||||||
|
// component_access
|
||||||
|
// .reads
|
||||||
|
// .extend(<(Ref<A>, Ref<B>) as View>::read_types().iter());
|
||||||
|
// component_access
|
||||||
|
// .writes
|
||||||
|
// .extend(<(Ref<A>, Ref<B>) as View>::write_types().iter());
|
||||||
|
|
||||||
|
// let run_fn = SystemFnWrapper(
|
||||||
|
// move |_,
|
||||||
|
// world,
|
||||||
|
// x: &mut PreparedRead<X>,
|
||||||
|
// query: &mut SystemQuery<
|
||||||
|
// (Ref<A>, Ref<B>),
|
||||||
|
// EntityFilterTuple<
|
||||||
|
// And<(ComponentFilter<A>, ComponentFilter<B>)>,
|
||||||
|
// And<(Passthrough, Passthrough)>,
|
||||||
|
// And<(Passthrough, Passthrough)>,
|
||||||
|
// >,
|
||||||
|
// >| {
|
||||||
|
// for (a, b) in query.iter_mut(world) {
|
||||||
|
// self(&*x, a, b);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// PhantomData,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// Box::new(System {
|
||||||
|
// name: name.into(),
|
||||||
|
// queries: AtomicRefCell::new(<(Ref<A>, Ref<B>)>::query()),
|
||||||
|
// access: SystemAccess {
|
||||||
|
// resources: resource_access,
|
||||||
|
// components: component_access,
|
||||||
|
// tags: Access::default(),
|
||||||
|
// },
|
||||||
|
// archetypes: ArchetypeAccess::Some(BitSet::default()),
|
||||||
|
// _resources: PhantomData::<PreparedRead<X>>,
|
||||||
|
// command_buffer: FxHashMap::default(),
|
||||||
|
// run_fn: AtomicRefCell::new(run_fn),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
impl<
|
||||||
|
'a,
|
||||||
|
F,
|
||||||
|
X: Resource + Send + Sync + 'static,
|
||||||
|
A: for<'b> View<'b> + DefaultFilter<Filter = AF> + ViewElement,
|
||||||
|
AF: EntityFilter + Sync + 'static,
|
||||||
|
B: for<'b> View<'b> + DefaultFilter<Filter = BF> + ViewElement,
|
||||||
|
BF: EntityFilter + Sync + 'static,
|
||||||
|
> IntoSystem<'a, (X,), (A, B)> for F
|
||||||
|
where
|
||||||
|
F: FnMut(&X, A, B) + Send + Sync + 'static,
|
||||||
|
<A as View<'a>>::Iter: Iterator<Item = A>,
|
||||||
|
<B as View<'a>>::Iter: Iterator<Item = B>,
|
||||||
|
{
|
||||||
|
fn into_system(mut self, name: &'static str) -> Box<dyn Schedulable> {
|
||||||
|
let mut resource_access: Access<ResourceTypeId> = Access::default();
|
||||||
|
resource_access
|
||||||
|
.reads
|
||||||
|
.extend(<PreparedRead<X>>::read_types().iter());
|
||||||
|
resource_access
|
||||||
|
.writes
|
||||||
|
.extend(<PreparedRead<X>>::write_types().iter());
|
||||||
|
let mut component_access: Access<ComponentTypeId> = 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 = SystemFnWrapper(
|
||||||
|
move |_,
|
||||||
|
world,
|
||||||
|
x: &mut PreparedRead<X>,
|
||||||
|
query: &mut SystemQuery<
|
||||||
|
(A, B),
|
||||||
|
EntityFilterTuple<
|
||||||
|
And<(
|
||||||
|
<AF as EntityFilter>::ArchetypeFilter,
|
||||||
|
<BF as EntityFilter>::ArchetypeFilter,
|
||||||
|
)>,
|
||||||
|
And<(
|
||||||
|
<AF as EntityFilter>::ChunksetFilter,
|
||||||
|
<BF as EntityFilter>::ChunksetFilter,
|
||||||
|
)>,
|
||||||
|
And<(
|
||||||
|
<AF as EntityFilter>::ChunkFilter,
|
||||||
|
<BF as EntityFilter>::ChunkFilter,
|
||||||
|
)>,
|
||||||
|
>,
|
||||||
|
>| {
|
||||||
|
for (a, b) in query.iter_mut(world) {
|
||||||
|
self(&*x, a, b);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PhantomData,
|
||||||
|
);
|
||||||
|
|
||||||
|
Box::new(System {
|
||||||
|
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::<PreparedRead<X>>,
|
||||||
|
command_buffer: FxHashMap::default(),
|
||||||
|
run_fn: AtomicRefCell::new(run_fn),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_system {
|
||||||
|
($(($view:ident, $filter:ident, $var:ident)),+) => {
|
||||||
|
impl<'a,
|
||||||
|
Func,
|
||||||
|
$($view: for<'b> View<'b> + DefaultFilter<Filter = $filter> + ViewElement,
|
||||||
|
$filter: EntityFilter + Sync + 'static),+
|
||||||
|
> IntoSystem<'a, (), ($($view,)+)> for Func
|
||||||
|
where
|
||||||
|
Func: FnMut($($view),+) + Send + Sync + 'static,
|
||||||
|
$(<$view as View<'a>>::Iter: Iterator<Item = $view>),+
|
||||||
|
{
|
||||||
|
fn into_system(mut self, name: &'static str) -> Box<dyn Schedulable> {
|
||||||
|
let resource_access: Access<ResourceTypeId> = Access::default();
|
||||||
|
let component_access: Access<ComponentTypeId> = component_access!(($($view),+));
|
||||||
|
|
||||||
|
let run_fn = SystemFnWrapper(
|
||||||
|
move |_,
|
||||||
|
world,
|
||||||
|
_: &mut (),
|
||||||
|
query: &mut system_query!($($view, $filter),+)
|
||||||
|
,
|
||||||
|
| {
|
||||||
|
for tuple!($($var),+) in query.iter_mut(world) {
|
||||||
|
self($($var),+);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PhantomData,
|
||||||
|
);
|
||||||
|
|
||||||
|
Box::new(System {
|
||||||
|
name: name.into(),
|
||||||
|
queries: AtomicRefCell::new(query!($($view),+)),
|
||||||
|
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! tuple {
|
||||||
|
// single value: v1
|
||||||
|
($value:ident) => { $value };
|
||||||
|
// multiple values: (v1, v2, v3)
|
||||||
|
($($value:ident),+) => { ($($value),+) }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! component_access {
|
||||||
|
(()) => {Access::default()};
|
||||||
|
(($($view:ident),+)) => {{
|
||||||
|
let mut component_access: Access<ComponentTypeId> = Access::default();
|
||||||
|
component_access
|
||||||
|
.reads
|
||||||
|
.extend(<tuple!($($view),+) as View>::read_types().iter());
|
||||||
|
component_access
|
||||||
|
.writes
|
||||||
|
.extend(<tuple!($($view),+) as View>::write_types().iter());
|
||||||
|
component_access
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! system_query {
|
||||||
|
($view:ident, $filter:ident) => {
|
||||||
|
SystemQuery<
|
||||||
|
$view,
|
||||||
|
$filter
|
||||||
|
>
|
||||||
|
};
|
||||||
|
($($view:ident, $filter:ident),+) => {
|
||||||
|
SystemQuery<
|
||||||
|
($($view),+),
|
||||||
|
EntityFilterTuple<
|
||||||
|
And<(
|
||||||
|
$(<$filter as EntityFilter>::ArchetypeFilter),+
|
||||||
|
)>,
|
||||||
|
And<(
|
||||||
|
$(<$filter as EntityFilter>::ChunksetFilter),+
|
||||||
|
)>,
|
||||||
|
And<(
|
||||||
|
$(<$filter as EntityFilter>::ChunkFilter),+
|
||||||
|
)>,
|
||||||
|
>
|
||||||
|
>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! query {
|
||||||
|
(()) => { () };
|
||||||
|
($($query:ident),+) => {
|
||||||
|
<tuple!($($query),+)>::query()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a)];
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a), (B, BF, b)];
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a), (B, BF, b), (C, CF, c)];
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d)];
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e)];
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl_system![(A, AF, a), (B, BF, b), (C, CF, c), (D, DF, d), (E, EF, e), (F, FF, f)];
|
||||||
|
#[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)];
|
||||||
|
#[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)];
|
||||||
|
#[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)];
|
||||||
|
#[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)];
|
||||||
|
#[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)];
|
||||||
|
#[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)];
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
into_resource_for_each_system,
|
into_resource_for_each_system,
|
||||||
resource::{PreparedRead, PreparedWrite, Resources},
|
resource::{PreparedRead, PreparedWrite, Resources},
|
||||||
|
IntoSystem,
|
||||||
};
|
};
|
||||||
use legion_core::{
|
use legion_core::{
|
||||||
borrow::{Ref, RefMut},
|
borrow::{Ref, RefMut},
|
||||||
@ -147,6 +375,29 @@ mod tests {
|
|||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
struct X(usize);
|
struct X(usize);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_into_system() {
|
||||||
|
// fn read_system(a: &A, x: Ref<X>, y: Ref<Y>) {
|
||||||
|
// println!("{} {} {}", a.0, x.0, y.0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn read_system(x: Ref<X>) {
|
||||||
|
// println!("{}", x.0);
|
||||||
|
// }
|
||||||
|
fn read_system(x: Ref<X>, y: Ref<Y>, mut z: RefMut<A>) {
|
||||||
|
z.0 += 1;
|
||||||
|
println!("{} {} {}", x.0, y.0, z.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut world = World::new();
|
||||||
|
let mut resources = Resources::default();
|
||||||
|
resources.insert(A(0));
|
||||||
|
world.insert((), vec![(X(1), Y(1)), (X(2), Y(2))]);
|
||||||
|
|
||||||
|
let mut system = read_system.into_system("hi");
|
||||||
|
system.run(&mut world, &mut resources);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_system_fn() {
|
fn test_system_fn() {
|
||||||
fn read_write_system(_: &mut (), (_x, mut y): (Ref<X>, RefMut<Y>)) { y.0 += 1; }
|
fn read_write_system(_: &mut (), (_x, mut y): (Ref<X>, RefMut<Y>)) { y.0 += 1; }
|
||||||
|
@ -6,8 +6,9 @@ fn main() {
|
|||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
.add_event::<MyEvent>()
|
.add_event::<MyEvent>()
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system_init(system_b)
|
.add_system_init(built_system)
|
||||||
.add_system(System::for_each("system_a", system_a))
|
.add_system(simple_system.into_system("simple_system"))
|
||||||
|
.add_system(closure_system())
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,31 +27,40 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
world.insert((), vec![(X(0), Y(1)), (X(2), Y(3))]);
|
world.insert((), vec![(X(0), Y(1)), (X(2), Y(3))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_a((x, y): (Ref<X>, RefMut<Y>)) {
|
// runs once for each entity with the X and Y component
|
||||||
|
fn simple_system(x: Ref<X>, mut y: RefMut<Y>) {
|
||||||
|
y.0 += 1;
|
||||||
|
println!("processed entity: {} {}", x.0, y.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn system_a(x: Ref<X>, mut y: RefMut<Y>) {
|
// does the same thing as the first system, but also captures the "counter" variable and uses it as internal state
|
||||||
|
fn closure_system() -> Box<dyn Schedulable> {
|
||||||
|
let mut counter = 0;
|
||||||
|
(move |x: Ref<X>, mut y: RefMut<Y>| {
|
||||||
|
y.0 += 1;
|
||||||
|
println!("processed entity: {} {}", x.0, y.0);
|
||||||
|
println!("ran {} times", counter);
|
||||||
|
counter += 1;
|
||||||
|
}).into_system("closure_system")
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
// if you need more flexibility, you can define complex systems using the system builder
|
||||||
// fn system_a((my_events, a): &mut (Resource<Events<MyEvent>>, Resource<A>), (x, mut y): (Ref<X>, RefMut<Y>)) {
|
fn built_system(resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn system_b(resources: &mut Resources) -> Box<dyn Schedulable> {
|
|
||||||
let mut my_event_reader = resources.get_event_reader::<MyEvent>();
|
let mut my_event_reader = resources.get_event_reader::<MyEvent>();
|
||||||
SystemBuilder::new("example")
|
SystemBuilder::new("example")
|
||||||
.read_resource::<Events<MyEvent>>()
|
.read_resource::<Events<MyEvent>>()
|
||||||
.write_resource::<A>()
|
.write_resource::<A>()
|
||||||
.with_query(<(Read<X>, Write<Y>)>::query())
|
.with_query(<(Read<X>, Write<Y>)>::query())
|
||||||
.build(move |_command_buffer, world, (my_events, ref mut a), query| {
|
.build(
|
||||||
for event in my_event_reader.iter(&my_events) {
|
move |_command_buffer, world, (my_events, ref mut a), query| {
|
||||||
a.0 += event.0;
|
for event in my_event_reader.iter(&my_events) {
|
||||||
println!("modified resource A with event: {}", event.0);
|
a.0 += event.0;
|
||||||
}
|
println!("modified resource A with event: {}", event.0);
|
||||||
for (x, mut y) in query.iter_mut(world) {
|
}
|
||||||
y.0 += 1;
|
for (x, mut y) in query.iter_mut(world) {
|
||||||
println!("processed entity: {} {}", x.0, y.0);
|
y.0 += 1;
|
||||||
}
|
println!("processed entity: {} {}", x.0, y.0);
|
||||||
})
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ pub use legion::{
|
|||||||
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
|
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
|
||||||
schedule::{Executor, Runnable, Schedulable, Schedule},
|
schedule::{Executor, Runnable, Schedulable, Schedule},
|
||||||
SubWorld, SystemBuilder,
|
SubWorld, SystemBuilder,
|
||||||
|
IntoSystem
|
||||||
},
|
},
|
||||||
world::{Universe, World},
|
world::{Universe, World},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user