mirror of
https://github.com/bevyengine/bevy
synced 2024-11-28 23:50:20 +00:00
Add docs & example for SystemParam (#1435)
It took me a little while to figure out how to use the `SystemParam` derive macro to easily create my own params. So I figured I'd add some docs and an example with what I learned. - Fixed a bug in the `SystemParam` derive macro where it didn't detect the correct crate name when used in an example (no longer relevant, replaced by #1426 - see further) - Added some doc comments and a short example code block in the docs for the `SystemParam` trait - Added a more complete example with explanatory comments in examples
This commit is contained in:
parent
b8a0ab01ba
commit
000dd4c1c2
5 changed files with 68 additions and 0 deletions
|
@ -260,6 +260,10 @@ path = "examples/ecs/state.rs"
|
||||||
name = "system_chaining"
|
name = "system_chaining"
|
||||||
path = "examples/ecs/system_chaining.rs"
|
path = "examples/ecs/system_chaining.rs"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "system_param"
|
||||||
|
path = "examples/ecs/system_param.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "timers"
|
name = "timers"
|
||||||
path = "examples/ecs/timers.rs"
|
path = "examples/ecs/timers.rs"
|
||||||
|
|
|
@ -338,6 +338,7 @@ struct SystemParamFieldAttributes {
|
||||||
|
|
||||||
static SYSTEM_PARAM_ATTRIBUTE_NAME: &str = "system_param";
|
static SYSTEM_PARAM_ATTRIBUTE_NAME: &str = "system_param";
|
||||||
|
|
||||||
|
/// Implement `SystemParam` to use a struct as a parameter in a system
|
||||||
#[proc_macro_derive(SystemParam, attributes(system_param))]
|
#[proc_macro_derive(SystemParam, attributes(system_param))]
|
||||||
pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
|
@ -5,6 +5,25 @@ use crate::{
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{any::TypeId, marker::PhantomData, sync::Arc};
|
use std::{any::TypeId, marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
|
/// A parameter that can be used in a system function
|
||||||
|
///
|
||||||
|
/// # Derive
|
||||||
|
/// This trait can be derived.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// use bevy_ecs::SystemParam;
|
||||||
|
///
|
||||||
|
/// #[derive(SystemParam)]
|
||||||
|
/// pub struct MyParam<'a> {
|
||||||
|
/// foo: Res<'a, usize>,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn my_system(param: MyParam) {
|
||||||
|
/// // Access the resource through `param.foo`
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub trait SystemParam: Sized {
|
pub trait SystemParam: Sized {
|
||||||
type Fetch: for<'a> FetchSystemParam<'a>;
|
type Fetch: for<'a> FetchSystemParam<'a>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ Example | File | Description
|
||||||
`startup_system` | [`ecs/startup_system.rs`](./ecs/startup_system.rs) | Demonstrates a startup system (one that runs once when the app starts up)
|
`startup_system` | [`ecs/startup_system.rs`](./ecs/startup_system.rs) | Demonstrates a startup system (one that runs once when the app starts up)
|
||||||
`state` | [`ecs/state.rs`](./ecs/state.rs) | Illustrates how to use States to control transitioning from a Menu state to an InGame state
|
`state` | [`ecs/state.rs`](./ecs/state.rs) | Illustrates how to use States to control transitioning from a Menu state to an InGame state
|
||||||
`system_chaining` | [`ecs/system_chaining.rs`](./ecs/system_chaining.rs) | Chain two systems together, specifying a return type in a system (such as `Result`)
|
`system_chaining` | [`ecs/system_chaining.rs`](./ecs/system_chaining.rs) | Chain two systems together, specifying a return type in a system (such as `Result`)
|
||||||
|
`system_param` | [`ecs/system_param.rs`](./ecs/system_param.rs) | Illustrates creating custom system parameters with `SystemParam`
|
||||||
`timers` | [`ecs/timers.rs`](./ecs/timers.rs) | Illustrates ticking `Timer` resources inside systems and handling their state
|
`timers` | [`ecs/timers.rs`](./ecs/timers.rs) | Illustrates ticking `Timer` resources inside systems and handling their state
|
||||||
|
|
||||||
## Games
|
## Games
|
||||||
|
|
43
examples/ecs/system_param.rs
Normal file
43
examples/ecs/system_param.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use bevy::{ecs::SystemParam, prelude::*};
|
||||||
|
|
||||||
|
/// This example creates a SystemParam struct that counts the number of players
|
||||||
|
fn main() {
|
||||||
|
App::build()
|
||||||
|
.insert_resource(PlayerCount(0))
|
||||||
|
.add_startup_system(spawn.system())
|
||||||
|
.add_system(count_players.system())
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Player;
|
||||||
|
struct PlayerCount(usize);
|
||||||
|
|
||||||
|
/// The SystemParam struct can contain any types that can also be included in a
|
||||||
|
/// system function signature.
|
||||||
|
///
|
||||||
|
/// In this example, it includes a query and a mutable resource.
|
||||||
|
#[derive(SystemParam)]
|
||||||
|
pub struct PlayerCounter<'a> {
|
||||||
|
players: Query<'a, &'a Player>,
|
||||||
|
count: ResMut<'a, PlayerCount>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PlayerCounter<'a> {
|
||||||
|
fn count(&mut self) {
|
||||||
|
self.count.0 = self.players.iter().len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Spawn some players to count
|
||||||
|
fn spawn(commands: &mut Commands) {
|
||||||
|
commands.spawn((Player,));
|
||||||
|
commands.spawn((Player,));
|
||||||
|
commands.spawn((Player,));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The SystemParam can be used directly in a system argument.
|
||||||
|
fn count_players(mut counter: PlayerCounter) {
|
||||||
|
counter.count();
|
||||||
|
|
||||||
|
println!("{} players in the game", counter.count.0);
|
||||||
|
}
|
Loading…
Reference in a new issue