-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a generic systems example to the examples folder in bevy. #2191
Conversation
So far this seems like a good starting point! A few logistical things,
Now with a few more suggestions
for example struct A;
struct B;
fn system<T>(_: Query<&T>) {}
fn main() {
App::build()
.add_system(system::<A>.system())
.add_system(system::<B>.system())
.run();
}
Again great start and please ask if you have any questions along the way! 😄 |
Awesome, thanks for contributing! You may also find this advice on writing examples helpful to you :) Nathan's advice above is great. You'll need to use I think it makes sense to think about when you want to use this pattern, and communicate that to users through your choice of example. To me, generic systems are useful when you need to perform the same operation on several distinct but similar component or resource types. In Bevy itself, we use it for events :) Coming up with those details is a lot of the fun of this work, but let us know if you'd like suggestions. P.S. This fits nicely into the |
Wow, thanks for all the advice and now I think I understand what the generic system should actually be doing. Thanks again! |
Hi @alice-i-cecile, I added the generic_systems to the examples for the README and Cargo.toml. Thanks! |
Hi @alice-i-cecile and @NathanSWard, I added mouse inputs in hopes that when either mouse left or right is clicked it would spawn an entity. |
FYI @AmrDhaliwal, as a PR author on GitHub you can press "Resolve Conversation" on comments in this thread. This makes it easier to skim and see which concerns still need to be addressed :) |
examples/ecs/generic_systems.rs
Outdated
let id = commands.spawn().insert(T).id(); | ||
info!("Spawned entity {:?} with component {}", id, std::any::type_name::<T>()); | ||
} | ||
mouse_button_inputs.just_pressed(MouseButton::Left); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line and the one below don't seem to do anything?
@NathanSWard Hopefully I got this right. |
examples/ecs/generic_systems.rs
Outdated
fn main() { | ||
App::build() | ||
.add_plugins(DefaultPlugins) | ||
.add_system(spawn_entities_on_click::<A>.system()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs the second type parameter to work :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alice-i-cecile do you mean the second parameter type for the function?
That's... not really how this works. Have you tried running the example you wrote? It doesn't compile, because the syntax is incorrect. I would also recommend using |
bors try |
tryBuild failed: |
You will need to add the example to the |
I tried my hand at my own generic system example for the book. Working with UI is way too verbose for that though :( Here's my almost-complete code; feel free to use or learn from it: use bevy::{app::AppExit, prelude::*};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(spawn_buttons_system)
// Events are automatically cleaned up using generic systems added with add_event!
.add_event::<Hello>()
.add_event::<Goodbye>()
// This system operates on buttons with a Hello component
.add_system(event_button_system::<Hello>)
// But this one only operates on those with a Goodbye component
.add_system(event_button_system::<Goodbye>)
// We're not using generic systems for event handling]
// because we need different behavior
.add_system(hello_system)
.add_system(goodbye_system)
.run()
}
// We're using these as both a components
// and event types
#[derive(Clone)]
struct Hello {
name: String,
}
#[derive(Clone)]
struct Goodbye;
fn spawn_buttons_system(mut commands: Commands) {
// We need a UI camera so we can see our buttons
commands.spawn_bundle(UiCameraBundle::default());
// We're quickly building 3 buttons in a UI hierarchy
// FIXME: add buttons
}
fn event_button_system<E: Send + Sync + Clone + 'static>(
// Interaction is the built-in type used to
// detect mouse interactions with buttons
query: Query<(&E, &Interaction)>,
mut writer: EventWriter<E>,
) {
// By using & here we can avoid dereferencing our unpacked components later
for (event_component, &interaction) in query.iter() {
if interaction == Interaction::Clicked {
// This will send any data stored in the component in the event as well
writer.send(event_component.clone());
}
}
}
fn hello_system(mut reader: EventReader<Hello>) {
for hello_event in reader.iter() {
println!("Hello {}!", hello_event.name);
}
}
// AppExit is a built-in event type that quits the app when it is received
fn goodbye_system(mut goodbye_reader: EventReader<Goodbye>, mut exit_writer: EventWriter<AppExit>) {
if goodbye_reader.iter().count() > 0 {
println!("Goodbye!");
exit_writer.send(AppExit);
}
} |
I'm going to close this out in favor of #2636 <3 |
Hi @alice-i-cecile,
Sorry this took me so long but, here's the code could you take a look and let
me know if I am heading in the right direction.
Thanks!