-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Increase upper limit of children!
#18865
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
Increase upper limit of children!
#18865
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
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 looks good to me. There's definitely easier ways to do this, but they all involve changing Spawn
stuff. This is a solid fix for now. Could you do the same thing for the spawn::related
macro? And then make children
call related
. That way its all together.
I moved the |
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.
LGTM!
Objective
Currently,
bevy_ecs
'schildren!
macro only supports spawning up to twelve children at once. Ideally there would be no limit.Solution
children!
is limited becauseSpawnableList
, the primary trait bound here, uses the fake variadics pattern on tuples of up to twelve elements. However, since a tuple itself implementsSpawnableList
, we can simply nest tuples of entities when we run out of room.This PR achieves this using
macro_rules
macros with a bit of brute force, following some discussion on Discord. If we create patterns for lists of up to eleven bundles, then use a repetition pattern to handle the rest, we can "special-case" the recursion into a nested tuple.In principle, this would permit an arbitrary number of children, but Rust's recursion limits will cut things short at around 1400 elements by default. Of course, it's generally not a good idea to stick that many bundles in a single invocation, but it might be worth mentioning in the docs.
Implementation notes
Why are cases 0-11 expanded by hand?
We could make use of a tertiary macro:
But I already feel a little bad exporting
recursive_spawn
. I'd really like to avoid exposing more internals, even if they are annotated with#[doc(hidden)]
. If I had to guess, I'd say it'll also make the expansion a tiny bit slower.Do we really need to handle up to twelve elements in the macro?
The macro is a little long, but doing it this way maximizes the "flatness" of the types to be spawned. This should improve the codegen a bit and makes the macro output a little bit easier to look at.
Future work
The
related!
macro is essentially the same aschildren!
, so if this direction is accepted,related!
should receive the same treatment. I imagine we'd want to extract out therecursive_spawn
macro into its own file since it can be used for both. If this should be tackled in this PR, let me know!Testing
This change is fairly trivial, but I added a single test to verify that it compiles and nothing goes wrong once recursion starts happening. It's pretty easy to verify that the change works in practice -- just spawn over twelve entities as children at once!