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::{
|
||||
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<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
|
||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
||||
|
@ -42,7 +52,7 @@ impl System {
|
|||
R: EntityFilter + Sync + '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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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<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
|
||||
Q: IntoQuery + DefaultFilter<Filter = R>,
|
||||
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
|
||||
|
@ -67,10 +106,7 @@ where
|
|||
|
||||
let component_access: Access<ComponentTypeId> = 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<X>, RefMut<Y>)) {
|
||||
y.0 += 1;
|
||||
}
|
||||
fn read_write_system(_: &mut (), (_x, mut y): (Ref<X>, RefMut<Y>)) { 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<MyEvent>()
|
||||
.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<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);
|
||||
}
|
||||
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<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},
|
||||
schedule::{Executor, Runnable, Schedulable, Schedule},
|
||||
SubWorld, SystemBuilder,
|
||||
into_system, into_resource_system
|
||||
},
|
||||
world::{Universe, World},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue