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

Allow spawning top-level entities from ChildBuilder #8812

Open
Shatur opened this issue Jun 11, 2023 · 4 comments
Open

Allow spawning top-level entities from ChildBuilder #8812

Shatur opened this issue Jun 11, 2023 · 4 comments
Labels
A-Hierarchy Parent-child entity hierarchies C-Usability A targeted quality-of-life change that makes Bevy easier to use X-Controversial There is active debate or serious implications around merging this PR

Comments

@Shatur
Copy link
Contributor

Shatur commented Jun 11, 2023

What problem does this solve or what need does it fill?

Sometimes you need to access to commands in order to spawn a top-level entity inside with_children to assign its parent later. I found it very useful for bevy_ui because the hierarchy could be very deep and there is no way to access commands in inner levels.
This was addressed #2817, but it was closed in favor of add_children from #4708, but add_children was removed in #6942.

What solution would you like?

Add a method to ChildBuilder that allow spawning entities outside of hierarchy.

What alternative(s) have you considered?

We could to consider re-opening #2817. It's a very small change.

@Shatur Shatur added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jun 11, 2023
@Shatur Shatur changed the title Add ChildBuilder::commands Allow spawning top-level entities from ChildBuilder Jun 11, 2023
@alice-i-cecile alice-i-cecile added A-Hierarchy Parent-child entity hierarchies and removed S-Needs-Triage This issue needs to be labelled labels Jun 11, 2023
@Selene-Amanita
Copy link
Member

Selene-Amanita commented Jun 11, 2023

Comments in PR #2448 raise concerns about how it might be confusing to have a commands method on ChildBuilder since parent.commands.spawn_empty() isn't immediately clear that it spawns an entity outside of the hierarchy.

add_command has a similar problem.

What name(s) would you suggest?

  • In the case of a spawn method: spawn_outside_of_hierarchy, spawn_as_top_level, spawn_detached, spawn_root (probably not this one), ...?*
  • Maybe even rename the current spawn in spawn_under, spawn_child, ...?*
  • In the case of a commands method: world_commands, raw_commands, commands_detached, top_level_commands, ...?**
  • Similarly, maybe rename add_command to add_top_level_command, add_raw_command, ...?
  • Something else entirely?

(* same for spawn_empty)
(** all of those could be inverted: commands_raw, detached_commands, ...)

@mockersf
Copy link
Member

Could you give more specific examples of what you would want to do with "top level" commands?

@Shatur
Copy link
Contributor Author

Shatur commented Jun 12, 2023

For example, to emulate tabs I mark my tab-buttons with struct TabContent(Entity). But in my UI tab go first, so I spawning a node for the buttons first, then I spawn tab content and then adding the tab to the spawning node. In order to do it, I need to spawn tab button as top level and assign parent to it. Currently I just have multiple commands in my system:

fn setup_system(mut commands: Commands, mut tab_commands: Commands) {
    commands
        .spawn((
            NodeBundle {
                style: Style {
                    flex_direction: FlexDirection::Column,
                    size: Size::all(Val::Percent(100.0)),
                    ..Default::default()
                },
                ..Default::default()
            },
            UiRoot,
        ))
        .with_children(|parent| {
            // Stores tab buttons.
            let tabs_entity = parent
                .spawn(NodeBundle {
                    style: Style {
                        justify_content: JustifyContent::Center,
                        ..Default::default()
                    },
                    ..Default::default()
                })
                .id();

            for (index, tab) in SettingsTab::iter().enumerate() {
                let content_entity = parent
                    .spawn(NodeBundle::default())
                    .with_children(|parent| {
                        // Spawn tab content depending on tab
                    })
                    .id();

                // Spawn button for the tab.
                tab_commands
                    .spawn((
                        TabContent(content_entity),
                        ExclusiveButton,
                        Pressed(index == 0),
                        ButtonBundle::default(),
                    ))
                    .set_parent(tabs_entity);
            }
        });
}

@Shatur
Copy link
Contributor Author

Shatur commented Jun 12, 2023

Another use case. I need to get an entity for my LabelEntity component, but I deep inside the hierarchy. Multiple commands in system helps, but would be way more convenient to just get commands from child builder:

    parent
        .spawn(NodeBundle {
            style: Style {
                size: Size::new(Val::Percent(50.0), Val::Percent(30.0)),
                ..Default::default()
            },
            ..Default::default()
        })
        .with_children(|parent| {
            let label_entity = label_commands.spawn(LabelBundle::large(theme, label)).id();
            parent
                .spawn(NodeBundle {
                    style: Style {
                        size: Size::all(Val::Percent(100.0)),
                        ..Default::default()
                    },
                    ..Default::default()
                })
                .add_child(label_entity);

            parent.spawn((button, LabelEntity(label_entity), ButtonBundle::default()));
        });

@alice-i-cecile alice-i-cecile added X-Controversial There is active debate or serious implications around merging this PR C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed C-Feature A new feature, making something new possible labels Sep 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Hierarchy Parent-child entity hierarchies C-Usability A targeted quality-of-life change that makes Bevy easier to use X-Controversial There is active debate or serious implications around merging this PR
Projects
None yet
Development

No branches or pull requests

4 participants