
# Objective #19649 introduced new `*_if_new` and `*_by_bundle_id_*` variations to `EntityClonerBuilder` filtering functionality, which resulted in increase in method permutations - there are now 8 allow variants to support various id types and 2 different insert modes. ## Solution This PR introduces a new trait `FilterableIds` to unify all id types and their `IntoIterator` implementations, which is somewhat similar to `WorldEntityFetch`. It supports `TypeId`, `ComponentId` and `BundleId`, allowing us to reduce the number of `allow` methods to 4: `allow`, `allow_if_new`, `allow_by_ids`, `allow_by_ids_if_new`. The function signature is a bit less readable now, but the docs mention types that can be passed in. ## Testing All existing tests pass, performance is unchanged. --------- Co-authored-by: urben1680 <55257931+urben1680@users.noreply.github.com>
4.0 KiB
title | pull_requests | ||
---|---|---|---|
EntityClonerBuilder Split |
|
EntityClonerBuilder
is now generic and has different methods depending on the generic.
To get the wanted one, EntityCloner::build
got split too:
EntityCloner::build_opt_out
to getEntityClonerBuilder<OptOut>
EntityCloner::build_opt_in
to getEntityClonerBuilder<OptIn>
The first is used to clone all components possible and optionally opting out of some. The second is used to only clone components as specified by opting in for them.
// 0.16
let mut builder = EntityCloner.build(&mut world);
builder.allow_all().deny::<ComponentThatShouldNotBeCloned>();
builder.clone_entity(source_entity, target_entity);
let mut builder = EntityCloner.build(&mut world);
builder.deny_all().allow::<ComponentThatShouldBeCloned>();
builder.clone_entity(source_entity, target_entity);
// 0.17
let mut builder = EntityCloner.build_opt_out(&mut world);
builder.deny::<ComponentThatShouldNotBeCloned>();
builder.clone_entity(source_entity, target_entity);
let mut builder = EntityCloner.build_opt_in(&mut world);
builder.allow::<ComponentThatShouldBeCloned>();
builder.clone_entity(source_entity, target_entity);
Still, using EntityClonerBuilder::finish
will return a non-generic EntityCloner
.
This change is done because the behavior of the two is too different to share the same struct and same methods and mixing them caused bugs.
The methods of the two builder types are different to 0.16 and to each other now:
Opt-Out variant
- Still offers variants of the
deny
methods. - No longer offers
allow
methods, you need to be exact with denying components. - Offers now the
insert_mode
method to configure if components are cloned if they already exist at the target. - Required components of denied components are no longer considered. Denying
A
, which requiresB
, does not implyB
alone would not be useful at the target. So if you do not want to cloneB
too, you need to deny it explicitly. This also means there is nowithout_required_components
method anymore as that would be redundant. - It is now the other way around: Denying
A
, which is required byC
, will now also denyC
. This can be bypassed with the newwithout_required_by_components
method.
Opt-In variant
- Still offers variants of the
allow
methods. - No longer offers
deny
methods, you need to be exact with allowing components. - Offers now
allow_if_new
method variants that only clone this component if the target does not contain it. If it does, required components of it will also not be cloned, except those that are also required by one that is actually cloned. - Still offers the
without_required_components
method.
Common methods
All other methods EntityClonerBuilder
had in 0.16 are still available for both variants:
with_default_clone_fn
move_components
clone_behavior
variantslinked_cloning
Unified id filtering
Previously EntityClonerBuilder
supported filtering by 2 types of ids: ComponentId
and TypeId
, the functions taking in IntoIterator
for them.
Since now EntityClonerBuilder
supports filtering by BundleId
as well, the number of method variations would become a bit too unwieldy.
Instead, all id filtering methods were unified into generic deny_by_ids/allow_by_ids(_if_new)
methods, which allow to filter components by
TypeId
, ComponentId
, BundleId
and their IntoIterator
variations.
Other affected APIs
0.16 | 0.17 |
---|---|
EntityWorldMut::clone_with |
EntityWorldMut::clone_with_opt_out EntityWorldMut::clone_with_opt_in |
EntityWorldMut::clone_and_spawn_with |
EntityWorldMut::clone_and_spawn_with_opt_out EntityWorldMut::clone_and_spawn_with_opt_in |
EntityCommands::clone_with |
EntityCommands::clone_with_opt_out EntityCommands::clone_with_opt_in |
EntityCommands::clone_and_spawn_with |
EntityCommands::clone_and_spawn_with_opt_out EntityCommands::clone_and_spawn_with_opt_in |
entity_command::clone_with |
entity_command::clone_with_opt_out entity_command::clone_with_opt_in |