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

Add CloneBundle command #3820

Closed
wants to merge 1 commit into from
Closed

Conversation

hlb8122
Copy link
Contributor

@hlb8122 hlb8122 commented Jan 31, 2022

Objective

Cloning one component from an entity to another entity is a common operation. It would make sense if this was supported out the box.

Solution

Create a clone_bundle API on EntityCommands which results in a CloneBundle command. The CloneBundle command peforms a EntityRef::get_bundle::<T> on the source entity, clones that provided reference, and then performs EntityMut::insert_bundle::<T> onto the target entity.

Notes

Similar to #3717

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Jan 31, 2022
@hlb8122 hlb8122 mentioned this pull request Jan 31, 2022
@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible and removed S-Needs-Triage This issue needs to be labelled labels Jan 31, 2022
@alice-i-cecile
Copy link
Member

The other big part of this design that you haven't outlined yet is a blanket impl for Clone on Bundle, if and only if all of the underlying component types are Clone. That will probably require the all_tuples meta-macro.

@hlb8122 hlb8122 marked this pull request as ready for review February 6, 2022 22:50
@alice-i-cecile alice-i-cecile self-requested a review February 10, 2022 17:54
@alice-i-cecile
Copy link
Member

This is a critical building block for #1515.

/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component, Clone)]
/// # struct Infected;
Copy link
Member

Choose a reason for hiding this comment

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

This would be much better motivated if it stored a value. Perhaps Infected{remaining_duration: Duration}?

Copy link
Contributor Author

@hlb8122 hlb8122 Feb 17, 2022

Choose a reason for hiding this comment

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

@alice-i-cecile At moment I've followed the other examples and hidden the Component in use (see remove/remove_bundle example). Just to clarify: you'd like me to un-# this and give it a field?

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

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

Simple, useful, correct. I have a few nits about the docs to improve clarity.

/// # struct Dummy;
/// #
/// # #[derive(Bundle, Clone)]
/// # struct Characteristics {
Copy link
Member

@alice-i-cecile alice-i-cecile Feb 17, 2022

Choose a reason for hiding this comment

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

IMO we should store multiple actual value-ful components here rather than fussing with Dummy. Just toss in strength / dexterity / intelligence perhaps?

Copy link
Contributor

@colepoirier colepoirier left a comment

Choose a reason for hiding this comment

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

Once @alice-i-cecile’s few nits are fixed this looks good to me!

@alice-i-cecile
Copy link
Member

Unsurprisingly, I think you should add clone_from to this PR.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 26, 2022
This may have occurred due to system order ambiguity, or if the spawning system has multiple command buffers", std::any::type_name::<T>(), self.source);
};

let bundle = if let Some(some) = source_mut.remove_bundle::<T>() {
Copy link
Member

Choose a reason for hiding this comment

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

This will trigger "removed events" (in RemovedComponents) for each component in the bundle, which is undesirable for a clone operation.

} else {
return;
};
source_mut.insert_bundle(bundle.clone());
Copy link
Member

Choose a reason for hiding this comment

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

This will trigger "added" and "changed" events for each component in the bundle, which is undesirable for a clone operation.

@hlb8122
Copy link
Contributor Author

hlb8122 commented Apr 18, 2022

The API and docs are reasonable quality.

Fixing the implementation is beyond me - waiting for an expert to come along and ressurect this.

@hlb8122 hlb8122 closed this Apr 18, 2022
@hlb8122 hlb8122 deleted the add-clone-bundle branch April 18, 2022 21:31
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 S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants