-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
FilteredEntityRef
conversions
#11838
Changes from 6 commits
0c9bc48
d2d1000
cebdfb1
7b2275c
c95e591
872110f
471611f
8863492
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -189,6 +189,58 @@ impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> { | |||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<FilteredEntityRef<'a>> for EntityRef<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: FilteredEntityRef<'a>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() { | ||||||
// SAFETY: check above guarantees read-only access to all components of the entity. | ||||||
Ok(unsafe { EntityRef::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<&'a FilteredEntityRef<'_>> for EntityRef<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: &'a FilteredEntityRef<'_>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() { | ||||||
// SAFETY: check above guarantees read-only access to all components of the entity. | ||||||
Ok(unsafe { EntityRef::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<FilteredEntityMut<'a>> for EntityRef<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: FilteredEntityMut<'a>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() { | ||||||
// SAFETY: check above guarantees read-only access to all components of the entity. | ||||||
Ok(unsafe { EntityRef::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<&'a FilteredEntityMut<'_>> for EntityRef<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: &'a FilteredEntityMut<'_>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() { | ||||||
// SAFETY: check above guarantees read-only access to all components of the entity. | ||||||
Ok(unsafe { EntityRef::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// Provides mutable access to a single entity and all of its components. | ||||||
/// | ||||||
/// Contrast with [`EntityWorldMut`], which allows adding and removing components, | ||||||
|
@@ -375,6 +427,32 @@ impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> { | |||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<FilteredEntityMut<'a>> for EntityMut<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: FilteredEntityMut<'a>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() && value.access.has_write_all() { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT: AFAIK you don't have to check for read all access, since it's impossible to have write_all access without read_all
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to keep this in as a failsafe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this guarantee something that we want to match the semantics of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's possible that we have write only access to certain data in the future. And more importantly, users can currently do this on their own. |
||||||
// SAFETY: check above guarantees exclusive access to all components of the entity. | ||||||
Ok(unsafe { EntityMut::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> TryFrom<&'a mut FilteredEntityMut<'_>> for EntityMut<'a> { | ||||||
type Error = (); | ||||||
|
||||||
fn try_from(value: &'a mut FilteredEntityMut<'_>) -> Result<Self, Self::Error> { | ||||||
if value.access.has_read_all() && value.access.has_write_all() { | ||||||
// SAFETY: check above guarantees exclusive access to all components of the entity. | ||||||
Ok(unsafe { EntityMut::new(value.entity) }) | ||||||
} else { | ||||||
Err(()) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// A mutable reference to a particular [`Entity`], and the entire world. | ||||||
/// This is essentially a performance-optimized `(Entity, &mut World)` tuple, | ||||||
/// which caches the [`EntityLocation`] to reduce duplicate lookups. | ||||||
|
@@ -1671,6 +1749,78 @@ impl<'a> From<&'a FilteredEntityMut<'_>> for FilteredEntityRef<'a> { | |||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: EntityRef<'a>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: &'a EntityRef<'_>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<EntityMut<'a>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: EntityMut<'a>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<&'a EntityMut<'_>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: &'a EntityMut<'_>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: EntityWorldMut<'a>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityWorldMut` guarantees exclusive access to the entire world. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.into_unsafe_entity_cell(), access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a> { | ||||||
fn from(entity: &'a EntityWorldMut<'_>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityWorldMut` guarantees exclusive access to the entire world. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
FilteredEntityRef::new(entity.as_unsafe_entity_cell_readonly(), access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`]. | ||||||
pub struct FilteredEntityMut<'w> { | ||||||
entity: UnsafeEntityCell<'w>, | ||||||
|
@@ -1848,6 +1998,58 @@ impl<'w> FilteredEntityMut<'w> { | |||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<EntityMut<'a>> for FilteredEntityMut<'a> { | ||||||
fn from(entity: EntityMut<'a>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
access.write_all(); | ||||||
FilteredEntityMut::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<&'a mut EntityMut<'_>> for FilteredEntityMut<'a> { | ||||||
fn from(entity: &'a mut EntityMut<'_>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
access.write_all(); | ||||||
FilteredEntityMut::new(entity.0, access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a> { | ||||||
fn from(entity: EntityWorldMut<'a>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityWorldMut` guarantees exclusive access to the entire world. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
access.write_all(); | ||||||
FilteredEntityMut::new(entity.into_unsafe_entity_cell(), access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a> { | ||||||
fn from(entity: &'a mut EntityWorldMut<'_>) -> Self { | ||||||
// SAFETY: | ||||||
// - `EntityWorldMut` guarantees exclusive access to the entire world. | ||||||
unsafe { | ||||||
let mut access = Access::default(); | ||||||
access.read_all(); | ||||||
access.write_all(); | ||||||
FilteredEntityMut::new(entity.as_unsafe_entity_cell(), access) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// Inserts a dynamic [`Bundle`] into the entity. | ||||||
/// | ||||||
/// # Safety | ||||||
|
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.
Does worth it adding an error for this conversion, so users may know why it failed, something like:
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.
Added the error enum, went with slightly different names to match the naming conventions for existing
TryFrom
errors, and also for variants of this existing error type