Skip to content
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

Implement System::system_metas(&self) and System::system_metas_mut(&mut self) for system exploration and configuration #16275

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Rajveer100
Copy link

Part of #16168

Objective

Implement System::system_metas(&self) and System::system_metas_mut(&mut self) for system exploration and configuration.

Solution

Introduce System::system_metas(&self) and System::system_metas_mut(&mut self) which would return iterator/vector/slice that we can work with.

Copy link
Contributor

github-actions bot commented Nov 7, 2024

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@Rajveer100
Copy link
Author

@alice-i-cecile
I am not quite sure if this is in the right direction.

@BenjaminBrienen BenjaminBrienen added C-Feature A new feature, making something new possible A-ECS Entities, components, systems, and events D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged S-Needs-Help The author needs help finishing this PR. labels Nov 7, 2024
@alice-i-cecile
Copy link
Member

@MiniaczQ, opinions?

@alice-i-cecile alice-i-cecile removed the S-Needs-Help The author needs help finishing this PR. label Nov 10, 2024
@alice-i-cecile
Copy link
Member

In all of the cases other than for piped systems, this method should return a vector with one element :)

@MiniaczQ
Copy link
Contributor

MiniaczQ commented Nov 10, 2024

Yeah, I didn't want to tackle this, because it's actually pretty technical.
I'd say the actual scope of this issue can be split into 3 steps.
If you can get the first one down, the rest is relatively easy as follow-up PRs.

Step 1

We definitely need a trait that has system_metas(&self) -> Vec<&SystemMeta> and system_metas_mut(&mut self) -> Vec<&mut SystemMeta>.
Implement it for all of the system types, sort of like what you did, just as a trait instead.

Now, to make this actually work, we need another set of methods (in that trait): extend_with_system_metas(&self, &mut Vec<&SystemMeta>) and extend_with_system_metas_mut(&mut self, &mut Vec<&mut SystemMeta>).
The original two methods will create a new Vec and fill it using the new methods.
Non-primitive systems like adapters and combinators will call the new methods on their sub-systems, while primitive systems will just append their own meta.
I'm not sure if the borrow checker will freak out here or not with the &mut.

Step 2

Then there is the matter of in-lining it.
This is not very appealing:

let mut my_system = IntoSystem::into_system(my_system);
my_system.system_metas_mut()[0].name = "abba".into();
app.add_systems(Update, my_system);

so we want a map_system_metas method (again, in the trait) that can do the same thing inline.

app.add_systems(Update, my_system.map_system_metas(|metas| { metas[0].name = "abba".into(); }));

no need for immutable variant.

Step 3

Sadly this isn't the end for this issue, we also should expose SystemMetas for schedule-configuration wrappers as well.
So implementing aforementioned trait on I believe SystemConfig and SystemSetConfig, I'd need to look it up to be sure.
This would allow us to do my_system.after(other_system).map_system_metas(...).

@BenjaminBrienen BenjaminBrienen added S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! labels Nov 10, 2024
@Rajveer100
Copy link
Author

Thanks for the detailed overview :)

@BenjaminBrienen BenjaminBrienen added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Nov 10, 2024
@Rajveer100
Copy link
Author

Rajveer100 commented Nov 11, 2024

@MiniaczQ
Let me know if the latest changes is the intended way. I think only the non-primitive systems remain:

  • AdapterSystems
  • CombinatorSystems
  • PipeSystems

@MiniaczQ
Copy link
Contributor

Looks good!
Looking through CI there seem to be no issues with borrow checker so far, hopefully it stays that way 🤞

@MiniaczQ MiniaczQ removed the D-Straightforward Simple bug fixes and API improvements, docs, test and examples label Nov 11, 2024
@Rajveer100 Rajveer100 force-pushed the expose-system-meta branch 2 times, most recently from 53059ae to c1b7131 Compare November 14, 2024 11:22
…(&mut self)`

for system exploration and configuration

Part of bevyengine#16168
@Rajveer100
Copy link
Author

Rajveer100 commented Nov 14, 2024

Done with non-primitive systems, if this looks fine we can work with the next steps.

fn system_metas_mut(&mut self) -> Vec<&mut SystemMeta>;

/// Helper method for `system_metas`.
fn extend_with_system_metas<'a>(&'a self, vec: &mut Vec<&'a SystemMeta>);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be better for these to take an impl Extend instead of a Vec. https://doc.rust-lang.org/core/iter/trait.Extend.html

Copy link
Contributor

@MiniaczQ MiniaczQ Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's neat, but I don't think it's appropriate to implement it here
Unless I don't understand your point

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was saying to change the function signature to fn extend_with_system_metas<'a>(&'a self, extendable: impl Extend<&'a SystemMeta>), which would allow the methods to take a bunch of the other std collections and not be limited to just a Vec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely missed the point then :)
I'm down for it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to take impl FnMut(&'a SystemMeta). That way, users that are just going to iterate over the result won't even have to allocate a Vec.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you recommend going with extend first?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, my point was that FnOnce is more general than Extend here. You'd still offer the version that returns a Vec!

fn for_each_system_meta<'a>(&'a self, f: impl FnOnce(&'a SystemMeta));

fn system_metas(&self) -> Vec<&SystemMeta> {
    let mut result = Vec::new();
    self.for_each_system_meta(|meta| result.push(meta));
    result
}

If someone wants to populate another type of collection, they can pass a closure that calls the relevant push method. But if they were just going to do for meta in system.system_metas() { ... } then they can avoid an allocation by calling system.for_each_system_meta(|meta| ...).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't be FnOnce since we use it many times, besides that makes sense, I voice no preference then

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea seems reasonable.

@chescock chescock closed this Nov 19, 2024
@chescock chescock reopened this Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants