-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Merged by Bors] - Lock down access to Entities #6740
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change a lot, and the docs are good. IMO this is essential for #6733, as it restricts users to the happy path.
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Jakob Hellermann <[email protected]>
Incorporated the changes from #3985 and reworded it to address the unresolved comments from that PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thought I had is that Entity: Reflect
which usually means that the fields are considered public and exposed. But we do impl_reflect_value
bevy/crates/bevy_ecs/src/reflect.rs
Line 404 in 3827316
impl_reflect_value!(Entity(Hash, PartialEq, Serialize, Deserialize)); |
so it is treated as an opaque identifier.
Exists(EntityLocation), | ||
DidNotExist, | ||
ExistsWithWrongGeneration, | ||
} | ||
|
||
impl Entity { | ||
#[cfg(test)] | ||
pub(crate) const fn new(index: u32, generation: u32) -> Entity { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the other methods on Entity
.
After this PR we still have
Entity::from_bits(Entity::to_bits(entity))
is still a perfect roundtripEntity::from_raw(index)
still exists and gives an entity withindex
andgeneration
0Entity::index()
andEntity::generation()
The use case from the docs of from_raw
could be replace with Entity::INVALID
. Do we know of other use cases, otherwise maybe replace it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually isn't a departure from the current status quo. Both fields were pub(crate)
before this so you couldn't create a raw entity outside of Entity::from_raw
before this PR.
The only time I can think of needing to construct a raw entity that isn't covered by serialization or reflection is for testing, for which there is no real need to round-trip it.
That last thread may be nice to address elsewhere, but shouldn't block this work :) bors r+ |
# Objective The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail. Addresses #3362 for `bevy_ecs::entity`. Incorporates the changes from #3985. ## Solution Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`. Additional cleanup for other parts of `bevy_ecs::entity`: - `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values. - `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it. - Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned. - `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search). - Attempted to document the few remaining undocumented public APIs in the module. --- ## Changelog Removed: `Entities`'s `Default` implementation. Removed: `EntityMeta` Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`. Co-authored-by: james7132 <[email protected]> Co-authored-by: James Liu <[email protected]>
Build failed (retrying...): |
Merge conflict. |
bors retry |
# Objective The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail. Addresses #3362 for `bevy_ecs::entity`. Incorporates the changes from #3985. ## Solution Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`. Additional cleanup for other parts of `bevy_ecs::entity`: - `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values. - `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it. - Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned. - `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search). - Attempted to document the few remaining undocumented public APIs in the module. --- ## Changelog Removed: `Entities`'s `Default` implementation. Removed: `EntityMeta` Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`. Co-authored-by: james7132 <[email protected]> Co-authored-by: James Liu <[email protected]>
# Objective The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail. Addresses bevyengine#3362 for `bevy_ecs::entity`. Incorporates the changes from bevyengine#3985. ## Solution Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`. Additional cleanup for other parts of `bevy_ecs::entity`: - `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values. - `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it. - Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned. - `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search). - Attempted to document the few remaining undocumented public APIs in the module. --- ## Changelog Removed: `Entities`'s `Default` implementation. Removed: `EntityMeta` Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`. Co-authored-by: james7132 <[email protected]> Co-authored-by: James Liu <[email protected]>
# Objective The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail. Addresses bevyengine#3362 for `bevy_ecs::entity`. Incorporates the changes from bevyengine#3985. ## Solution Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`. Additional cleanup for other parts of `bevy_ecs::entity`: - `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values. - `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it. - Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned. - `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search). - Attempted to document the few remaining undocumented public APIs in the module. --- ## Changelog Removed: `Entities`'s `Default` implementation. Removed: `EntityMeta` Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`. Co-authored-by: james7132 <[email protected]> Co-authored-by: James Liu <[email protected]>
# Objective The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail. Addresses bevyengine#3362 for `bevy_ecs::entity`. Incorporates the changes from bevyengine#3985. ## Solution Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`. Additional cleanup for other parts of `bevy_ecs::entity`: - `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values. - `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it. - Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned. - `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search). - Attempted to document the few remaining undocumented public APIs in the module. --- ## Changelog Removed: `Entities`'s `Default` implementation. Removed: `EntityMeta` Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`. Co-authored-by: james7132 <[email protected]> Co-authored-by: James Liu <[email protected]>
Objective
The soundness of the ECS
World
partially relies on the correctness of the state ofEntities
stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using aWorld
. While this is not strictly unsound so long as users (includingbevy_render
) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail.Addresses #3362 for
bevy_ecs::entity
. Incorporates the changes from #3985.Solution
Remove
Entities
'sDefault
implementation and force access to the type to only be through a properly constructedWorld
.Additional cleanup for other parts of
bevy_ecs::entity
:Entity::index
andEntity::generation
are no longerpub(crate)
, opting to force the rest of bevy_ecs to use the public interface to access these values.EntityMeta
is no longerpub
and also notpub(crate)
to attempt to cut down on updatinggeneration
without going through anEntities
API. It's currently inaccessible except via thepub(crate)
Vec onEntities
, there was no way for an outside user to use it.Entities::set
, an unsafepub(crate)
API for setting the location of an Entity (parallel toEntities::get
) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned.Entities::alloc_at_without_replacement
is only used inWorld::get_or_spawn
within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search).Changelog
Removed:
Entities
'sDefault
implementation.Removed:
EntityMeta
Removed:
Entities::alloc_at_without_replacement
andAllocAtWithoutReplacement
.Migration Guide
Entities
'sDefault
implementation has been removed. You can fetch a reference to aWorld
'sEntities
viaWorld::entities
andWorld::entities_mut
.Entities::alloc_at_without_replacement
andAllocAtWithoutReplacement
has been made private due to difficulty in using it properly outside ofbevy_ecs
. If you still need use of this API, please file an issue.