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

Make the MapEntities trait generic over Mappers, and add a simpler EntityMapper #11428

Merged
merged 22 commits into from
Jan 28, 2024

Conversation

cBournhonesque
Copy link
Contributor

@cBournhonesque cBournhonesque commented Jan 20, 2024

Objective

My motivation are to resolve some of the issues I describe in this PR:

  • not being able to easily mapping entities because the current EntityMapper requires &mut World access
  • not being able to create my own EntityMapper because some components (Parent or Children) do not provide any public way of modifying the inner entities

This PR makes the MapEntities trait accept a generic type that implements Mapper to perform the mapping.
This means we don't need to use EntityMapper to perform our mapping, we can use any type that implements Mapper. Basically this change is very similar to what serde does. Instead of specifying directly how to map entities for a given type, we have 2 distinct steps:

  • the user implements MapEntities to define how the type will be traversed and which Entitys will be mapped
  • the Mapper defines how the mapping is actually done
    This is similar to the distinction between Serialize (MapEntities) and Serializer (Mapper).

This allows networking library to map entities without having to use the existing EntityMapper (which requires &mut World access and the use of world_scope())

Migration Guide

  • The existing EntityMapper (notably used to replicate Scenes across different Worlds) has been renamed to SceneEntityMapper

  • The MapEntities trait now works with a generic EntityMapper instead of the specific struct EntityMapper.
    Calls to fn map_entities(&mut self, entity_mapper: &mut EntityMapper) need to be updated to
    fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M)

  • The new trait EntityMapper has been added to the prelude

@cBournhonesque cBournhonesque added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Scenes Serialized ECS data stored on the disk labels Jan 20, 2024
Copy link
Contributor

@SkiFire13 SkiFire13 left a comment

Choose a reason for hiding this comment

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

An issue I have with this implementation is that everyone using MapEntities will be forced to implement both methods, even though most of the time they will only use one of them.

crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
@cBournhonesque
Copy link
Contributor Author

cBournhonesque commented Jan 20, 2024

An issue I have with this implementation is that everyone using MapEntities will be forced to implement both methods, even though most of the time they will only use one of them.

I agree that this is not acceptable; there must be a better solution, maybe something like:

fn map_entities<M: Mapper>(&mut self, entity_mapper: M);

where M
can be either &mut EntityMapper or &SimpleEntityMapper

Also I really don't like the names

@cBournhonesque cBournhonesque changed the title Add a simpler EntityMapper Make the MapEntities trait generic over Mappers, and add a simpler EntityMapper Jan 20, 2024
}

/// Similar to `EntityMapper`, but does not allocate new [`Entity`] references in case we couldn't map the entity.
pub struct SimpleEntityMapper<'m> {
Copy link
Contributor

@Shatur Shatur Jan 24, 2024

Choose a reason for hiding this comment

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

It's never used inside Bevy, I would remove it and left its implementation to users.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm maybe

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I'm mostly not sure on why you would want this behavior. If that can be clearly demonstrated with docs (and tested) I'd be fine to ship it.

Copy link
Contributor Author

@cBournhonesque cBournhonesque Jan 26, 2024

Choose a reason for hiding this comment

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

That's the behaviour I'd prefer to have for networking, as I don't want/need the complexities associated with the existing EntityMapper. (Having to use EntityMapper::world_scope() and needing access to &mut World)
I will remove this from the PR as users can implement it themselves

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. I'd happily accept a PR to add it with docs, but I agree, it can be split out from this.

crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Shatur Shatur left a comment

Choose a reason for hiding this comment

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

Left a couple of nits and suggestions :)

crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
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.

LGTM once the SceneEntityMapper rename is done and CI is green (duplicate dependencies can fail).

crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/reflect/map_entities.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Shatur Shatur left a comment

Choose a reason for hiding this comment

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

Thank you a lot!

@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 Jan 26, 2024
@alice-i-cecile
Copy link
Member

Just needs formatting now :) I'm going to merge this on Monday to leave time for other opinions to trickle in, but this should be in 0.13.

@cBournhonesque
Copy link
Contributor Author

Exciting!
Thanks to you all for your speedy and thorough reviews <3

Copy link
Contributor

@UkoeHB UkoeHB left a comment

Choose a reason for hiding this comment

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

Just some docs, looks good otherwise.

crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/entity/map_entities.rs Outdated Show resolved Hide resolved
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jan 28, 2024
@alice-i-cecile alice-i-cecile removed this pull request from the merge queue due to a manual request Jan 28, 2024
Co-authored-by: UkoeHB <[email protected]>
@alice-i-cecile
Copy link
Member

Applied the last suggestion: I think it was a modest improvement. Merging now :)

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jan 28, 2024
Merged via the queue into bevyengine:main with commit 9223201 Jan 28, 2024
22 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Jan 29, 2024
# Objective

Fixes: #11549 

Add a doctest example of what a custom implementation of an
`EntityMapper` would look like.

(need to wait until #11428 is
merged)

---------

Co-authored-by: Charles Bournhonesque <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Hennadii Chernyshchyk <[email protected]>
tjamaan pushed a commit to tjamaan/bevy that referenced this pull request Feb 6, 2024
…tityMapper (bevyengine#11428)

# Objective

My motivation are to resolve some of the issues I describe in this
[PR](bevyengine#11415):
- not being able to easily mapping entities because the current
EntityMapper requires `&mut World` access
- not being able to create my own `EntityMapper` because some components
(`Parent` or `Children`) do not provide any public way of modifying the
inner entities

This PR makes the `MapEntities` trait accept a generic type that
implements `Mapper` to perform the mapping.
This means we don't need to use `EntityMapper` to perform our mapping,
we can use any type that implements `Mapper`. Basically this change is
very similar to what `serde` does. Instead of specifying directly how to
map entities for a given type, we have 2 distinct steps:
- the user implements `MapEntities` to define how the type will be
traversed and which `Entity`s will be mapped
  - the `Mapper` defines how the mapping is actually done
This is similar to the distinction between `Serialize` (`MapEntities`)
and `Serializer` (`Mapper`).

This allows networking library to map entities without having to use the
existing `EntityMapper` (which requires `&mut World` access and the use
of `world_scope()`)


## Migration Guide
- The existing `EntityMapper` (notably used to replicate `Scenes` across
different `World`s) has been renamed to `SceneEntityMapper`

- The `MapEntities` trait now works with a generic `EntityMapper`
instead of the specific struct `EntityMapper`.
Calls to `fn map_entities(&mut self, entity_mapper: &mut EntityMapper)`
need to be updated to
`fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M)`

- The new trait `EntityMapper` has been added to the prelude

---------

Co-authored-by: Charles Bournhonesque <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: UkoeHB <[email protected]>
tjamaan pushed a commit to tjamaan/bevy that referenced this pull request Feb 6, 2024
# Objective

Fixes: bevyengine#11549 

Add a doctest example of what a custom implementation of an
`EntityMapper` would look like.

(need to wait until bevyengine#11428 is
merged)

---------

Co-authored-by: Charles Bournhonesque <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Hennadii Chernyshchyk <[email protected]>
brianreavis added a commit to naturalatlas/bevy_xpbd that referenced this pull request Feb 6, 2024
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 A-Scenes Serialized ECS data stored on the disk C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide 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.

6 participants