bevy icon indicating copy to clipboard operation
bevy copied to clipboard

bevy_ecs: add untyped methods for inserting components and bundles

Open jakobhellermann opened this issue 3 years ago • 6 comments

Objective

  • #4447 implemented untyped (using component ids instead of generics and TypeId) APIs for inserting/accessing resources and accessing components, but left inserting components for another PR (this one)

Solution

  • add EntityMut::{insert_by_id, insert_bundle_by_id}
  • split Bundle into DynamicBundle with get_components and Bundle: DynamicBundle. This allows the BundleInserter machinery to be reused for bundles that can only be written, not read, and have no statically available ComponentIds
  • add Bundles::bundle_ids_dynamic: HashMap<Vec<ComponentId>, BundleId> next to the HashMap<TypeId, BundleId>

Changelog

  • add methods for inserting bundles and components to: world.entity_mut(entity).insert_bundle_by_id/insert_by_id

Unresolved questions

  • can we get rid of some allocations?

    • init_info_dynamic could remove a .clone() of a Vec<ComponentId> when HashMap::raw_entry stabilizes
    • insert_by_id could not reuse insert_bundle_by_id to avoid the Vec overhead, or alternatively insert_bundle_by_id could maybe be changed to not require the Vec for the OwningPtrs
  • currently insert_bundle_by_ids requires takes a Vec<ComponentId> that must be sorted and a Vec<OwningPtr<'_> that must match the component ids. This is because internally we also need the Vec<ComponentId> so if the caller already has it we can just use that.

    • should we just accept a &[(ComponentId, OwningPtr<'_>)] and internally collect that into a sorted vec of component ids?
    • [x] alternatively, should we sort the ComponentId vec in the function so that we don't have such a subtle safety requirement? sorting an already sorted vec is the best case scenario for insertion sort (which is used for std sort for <=20 elements) so it's just a small O(n) cost

jakobhellermann avatar Aug 07 '22 10:08 jakobhellermann

Pining here to see if there is any plans to pursue this PR? I wanted to pick up #5074 however, it relies on a DynamicBundle like interface (which is what this PR provides). I can always adopt this PR, at the discretion of @jakobhellermann of course.

NathanSWard avatar Aug 26 '22 17:08 NathanSWard

ping @jakobhellermann Any plans to move forward w/ this PR? I'm more than happy to take it over if that's easier.

NathanSWard avatar Sep 02 '22 06:09 NathanSWard

ping @jakobhellermann Any plans to move forward w/ this PR? I'm more than happy to take it over if that's easier.

Sorry for not responding earlier. I'm a bit busy with Uni right now but feel free to adopt this PR.

jakobhellermann avatar Sep 02 '22 07:09 jakobhellermann

I rebased the PR and adressed the review comments.

It's not quite ready for review yet because I made the DynamicBundle trait safe because I noticed that it had no actual safety requirements anymore and need to properly think about it to make sure that is correct. Also I don't know if Drop logic is correct right now, so I need to look into that as well. I will do both tomorrow probably.

jakobhellermann avatar Sep 20 '22 18:09 jakobhellermann

rebased the PR

jakobhellermann avatar Oct 28 '22 19:10 jakobhellermann

This PR looks amazing and is super helpful!

I was looking into implementing something similar and would like to throw a suggestion up for discussion,

Would it be possible to move the ComponentId correctness check into init_info_dynamic which could be made safe and public?

The resulting BundleId could be stored by the user and used in fn insert_bundle_by_ids(&mut self, bundle_id, ...).

This would have the added benefit of being able to remove bundle_ids_dynamic, and init_info_dynamic would document that all dynamic queries will be assigned a unique BundleId (this is akin to what happens to "Components::init_component_with_descriptor").

Could rename init_info_dynamic to init_dynamic_bundle.

EDIT: Dumped the changes in https://github.com/jakobhellermann/bevy/pull/69

Suficio avatar Nov 11 '22 00:11 Suficio

Controversial because we need to decide between this and #7204 :)

alice-i-cecile avatar Jan 15 '23 16:01 alice-i-cecile