mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
some system_fn renaming and add system examples
This commit is contained in:
parent
713c4a6056
commit
f1a03a7a3a
6 changed files with 111 additions and 46 deletions
|
@ -1,8 +1,8 @@
|
||||||
use legion::{
|
use legion::{
|
||||||
filter::EntityFilter,
|
filter::EntityFilter,
|
||||||
prelude::{
|
prelude::{
|
||||||
into_resource_system, into_system, IntoQuery, ResourceSet, Resources, Runnable,
|
into_resource_system, IntoQuery, ResourceSet, Resources, Runnable,
|
||||||
Schedulable, World,
|
Schedulable, World, into_resource_for_each_system, into_for_each_system,
|
||||||
},
|
},
|
||||||
query::{DefaultFilter, View},
|
query::{DefaultFilter, View},
|
||||||
};
|
};
|
||||||
|
@ -34,7 +34,17 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl System {
|
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<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
|
||||||
where
|
where
|
||||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
Q: IntoQuery + DefaultFilter<Filter = R>,
|
||||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
||||||
|
@ -42,7 +52,7 @@ impl System {
|
||||||
R: EntityFilter + Sync + 'static,
|
R: EntityFilter + Sync + 'static,
|
||||||
X: ResourceSet<PreparedResources = X> + 'static,
|
X: ResourceSet<PreparedResources = X> + '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
|
pub fn resource<'a, F, X>(name: &'static str, system: F) -> Self
|
||||||
|
|
|
@ -16,6 +16,6 @@ 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_system, into_resource_system
|
into_for_each_system, into_resource_system, into_resource_for_each_system,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,56 @@ use crate::{
|
||||||
schedule::{ArchetypeAccess, Schedulable},
|
schedule::{ArchetypeAccess, Schedulable},
|
||||||
Access, System, SystemAccess, SystemFnWrapper, SystemQuery,
|
Access, System, SystemAccess, SystemFnWrapper, SystemQuery,
|
||||||
};
|
};
|
||||||
|
use bit_set::BitSet;
|
||||||
use fxhash::FxHashMap;
|
use fxhash::FxHashMap;
|
||||||
use legion_core::{
|
use legion_core::{
|
||||||
borrow::{AtomicRefCell},
|
borrow::AtomicRefCell,
|
||||||
filter::EntityFilter,
|
filter::EntityFilter,
|
||||||
query::{DefaultFilter, IntoQuery, View},
|
query::{DefaultFilter, IntoQuery, View},
|
||||||
storage::{ComponentTypeId},
|
storage::ComponentTypeId,
|
||||||
};
|
};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use bit_set::BitSet;
|
|
||||||
|
|
||||||
pub fn into_system<'a, Q, F, R, X>(name: &'static str, mut system: F) -> Box<dyn Schedulable>
|
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>(
|
||||||
|
name: &'static str,
|
||||||
|
mut system: F,
|
||||||
|
) -> Box<dyn Schedulable>
|
||||||
where
|
where
|
||||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
Q: IntoQuery + DefaultFilter<Filter = R>,
|
||||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
||||||
|
@ -67,10 +106,7 @@ where
|
||||||
|
|
||||||
let component_access: Access<ComponentTypeId> = Access::default();
|
let component_access: Access<ComponentTypeId> = Access::default();
|
||||||
let run_fn = SystemFnWrapper(
|
let run_fn = SystemFnWrapper(
|
||||||
move |_,
|
move |_, _, resources: &mut X, _| {
|
||||||
_,
|
|
||||||
resources: &mut X,
|
|
||||||
_| {
|
|
||||||
system(resources);
|
system(resources);
|
||||||
},
|
},
|
||||||
PhantomData,
|
PhantomData,
|
||||||
|
@ -93,8 +129,8 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::into_system;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
into_resource_for_each_system,
|
||||||
resource::{PreparedRead, PreparedWrite, Resources},
|
resource::{PreparedRead, PreparedWrite, Resources},
|
||||||
};
|
};
|
||||||
use legion_core::{
|
use legion_core::{
|
||||||
|
@ -113,15 +149,13 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_system_fn() {
|
fn test_system_fn() {
|
||||||
fn read_write_system(_: &mut (), (_x, mut y): (Ref<X>, RefMut<Y>)) {
|
fn read_write_system(_: &mut (), (_x, mut y): (Ref<X>, RefMut<Y>)) { y.0 += 1; }
|
||||||
y.0 += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
let mut resources = Resources::default();
|
let mut resources = Resources::default();
|
||||||
world.insert((), vec![(X(1), Y(1)), (X(2), Y(2))]);
|
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);
|
system.run(&mut world, &mut resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +188,7 @@ mod tests {
|
||||||
resources.insert(A(0));
|
resources.insert(A(0));
|
||||||
resources.insert(B(1));
|
resources.insert(B(1));
|
||||||
world.insert((), vec![(X(2), Y(3)), (X(4), Y(5))]);
|
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);
|
my_system.run(&mut world, &mut resources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ fn main() {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(System::resource_for("move", move_system))
|
.add_system(System::resource_for_each("move", move_system))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,56 @@
|
||||||
use bevy::{
|
use bevy::prelude::*;
|
||||||
input::mouse::{MouseButtonInput, MouseMotion},
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/// Illustrates the different ways you can declare systems
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
.add_system_init(mouse_input_system)
|
.add_event::<MyEvent>()
|
||||||
|
.add_startup_system(setup)
|
||||||
|
.add_system_init(system_b)
|
||||||
|
.add_system(System::for_each("system_a", system_a))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// prints out mouse events as they come in
|
struct MyEvent(usize);
|
||||||
pub fn mouse_input_system(resources: &mut Resources) -> Box<dyn Schedulable> {
|
|
||||||
let mut mouse_button_input_event_reader = resources.get_event_reader::<MouseButtonInput>();
|
|
||||||
let mut mouse_motion_event_reader = resources.get_event_reader::<MouseMotion>();
|
|
||||||
SystemBuilder::new("mouse_input")
|
|
||||||
.read_resource::<Events<MouseButtonInput>>()
|
|
||||||
.read_resource::<Events<MouseMotion>>()
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for event in mouse_motion_event_reader.iter(&mouse_motion_events) {
|
// resources
|
||||||
println!("{:?}", event);
|
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<X>, RefMut<Y>)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn system_a(x: Ref<X>, mut y: RefMut<Y>) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// fn system_a((my_events, a): &mut (Resource<Events<MyEvent>>, Resource<A>), (x, mut y): (Ref<X>, RefMut<Y>)) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn system_b(resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||||
|
let mut my_event_reader = resources.get_event_reader::<MyEvent>();
|
||||||
|
SystemBuilder::new("example")
|
||||||
|
.read_resource::<Events<MyEvent>>()
|
||||||
|
.write_resource::<A>()
|
||||||
|
.with_query(<(Read<X>, Write<Y>)>::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);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ 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,
|
||||||
into_system, into_resource_system
|
|
||||||
},
|
},
|
||||||
world::{Universe, World},
|
world::{Universe, World},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue