entity refs can have no location
This commit is contained in:
parent
58ee663ece
commit
85b0d03dec
@ -487,7 +487,10 @@ impl EntityCloner {
|
|||||||
#[cfg(not(feature = "bevy_reflect"))]
|
#[cfg(not(feature = "bevy_reflect"))]
|
||||||
let app_registry = Option::<()>::None;
|
let app_registry = Option::<()>::None;
|
||||||
|
|
||||||
let archetype = source_entity.archetype();
|
let Some(archetype) = source_entity.archetype() else {
|
||||||
|
// If the source has no archetype, there is nothing to clone.
|
||||||
|
return target;
|
||||||
|
};
|
||||||
bundle_scratch = BundleScratch::with_capacity(archetype.component_count());
|
bundle_scratch = BundleScratch::with_capacity(archetype.component_count());
|
||||||
|
|
||||||
for component in archetype.components() {
|
for component in archetype.components() {
|
||||||
|
|||||||
@ -782,20 +782,19 @@ impl Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`EntityLocation`] of an [`Entity`].
|
/// Returns the [`EntityLocation`] of an [`Entity`].
|
||||||
/// Note: for pending entities and entities not participating in the ECS (entities with a [`EntityIdLocation`] of `None`), returns `None`.
|
/// Note: for non-constructed entities, returns `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self, entity: Entity) -> Option<EntityLocation> {
|
pub fn get(&self, entity: Entity) -> Option<EntityLocation> {
|
||||||
self.get_id_location(entity).flatten()
|
self.get_id_location(entity).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`EntityIdLocation`] of an [`Entity`].
|
/// Returns the [`EntityIdLocation`] of an [`Entity`].
|
||||||
/// Note: for pending entities, returns `None`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_id_location(&self, entity: Entity) -> Option<EntityIdLocation> {
|
pub fn get_id_location(&self, entity: Entity) -> Option<EntityIdLocation> {
|
||||||
self.meta
|
match self.meta.get(entity.index() as usize) {
|
||||||
.get(entity.index() as usize)
|
Some(meta) => (meta.generation == entity.generation).then_some(meta.location),
|
||||||
.filter(|meta| meta.generation == entity.generation)
|
None => (entity.generation() == EntityGeneration::FIRST).then_some(None),
|
||||||
.map(|meta| meta.location)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the entity exists in the world *now*:
|
/// Returns true if the entity exists in the world *now*:
|
||||||
|
|||||||
@ -353,6 +353,36 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn construct_and_destruct() {
|
||||||
|
let mut world = World::new();
|
||||||
|
let e1 = world.spawn_null();
|
||||||
|
world.construct(e1, (TableStored("abc"), A(123))).unwrap();
|
||||||
|
let e2 = world.spawn_null();
|
||||||
|
assert!(world.destruct(e2).is_some());
|
||||||
|
assert!(world.despawn(e2));
|
||||||
|
let e3 = world.spawn_null();
|
||||||
|
let mut e3 = world.entity_mut(e3);
|
||||||
|
e3.destruct();
|
||||||
|
e3.despawn();
|
||||||
|
let e4 = world.spawn_null();
|
||||||
|
world
|
||||||
|
.entity_mut(e4)
|
||||||
|
.construct((TableStored("junk"), A(0)))
|
||||||
|
.unwrap()
|
||||||
|
.destruct()
|
||||||
|
.construct((TableStored("def"), A(456)))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(world.entities.count_active(), 2);
|
||||||
|
assert!(world.despawn(e1));
|
||||||
|
assert_eq!(world.entities.count_active(), 1);
|
||||||
|
assert!(world.get::<TableStored>(e1).is_none());
|
||||||
|
assert!(world.get::<A>(e1).is_none());
|
||||||
|
assert_eq!(world.get::<TableStored>(e4).unwrap().0, "def");
|
||||||
|
assert_eq!(world.get::<A>(e4).unwrap().0, 456);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn despawn_table_storage() {
|
fn despawn_table_storage() {
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use crate::{
|
|||||||
event::{Event, EventId, Events, SendBatchIds},
|
event::{Event, EventId, Events, SendBatchIds},
|
||||||
observer::{Observers, TriggerTargets},
|
observer::{Observers, TriggerTargets},
|
||||||
prelude::{Component, QueryState},
|
prelude::{Component, QueryState},
|
||||||
query::{QueryData, QueryFilter},
|
query::{DebugCheckedUnwrap, QueryData, QueryFilter},
|
||||||
relationship::RelationshipHookMode,
|
relationship::RelationshipHookMode,
|
||||||
resource::Resource,
|
resource::Resource,
|
||||||
system::{Commands, Query},
|
system::{Commands, Query},
|
||||||
@ -144,7 +144,8 @@ impl<'w> DeferredWorld<'w> {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let archetype = &raw const *entity_cell.archetype();
|
// SAFETY: If the archetype was none, it would not have the component on it.
|
||||||
|
let archetype = unsafe { &raw const *entity_cell.archetype().debug_checked_unwrap() };
|
||||||
|
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// - DeferredWorld ensures archetype pointer will remain valid as no
|
// - DeferredWorld ensures archetype pointer will remain valid as no
|
||||||
|
|||||||
@ -215,12 +215,12 @@ unsafe impl WorldEntityFetch for Entity {
|
|||||||
) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
|
) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
|
||||||
let location = cell
|
let location = cell
|
||||||
.entities()
|
.entities()
|
||||||
.get(self)
|
.get_id_location(self)
|
||||||
.ok_or(EntityDoesNotExistError::new(self, cell.entities()))?;
|
.ok_or(EntityDoesNotExistError::new(self, cell.entities()))?;
|
||||||
// SAFETY: caller ensures that the world cell has mutable access to the entity.
|
// SAFETY: caller ensures that the world cell has mutable access to the entity.
|
||||||
let world = unsafe { cell.world_mut() };
|
let world = unsafe { cell.world_mut() };
|
||||||
// SAFETY: location was fetched from the same world's `Entities`.
|
// SAFETY: location was fetched from the same world's `Entities`.
|
||||||
Ok(unsafe { EntityWorldMut::new(world, self, Some(location)) })
|
Ok(unsafe { EntityWorldMut::new(world, self, location) })
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn fetch_deferred_mut(
|
unsafe fn fetch_deferred_mut(
|
||||||
|
|||||||
@ -78,13 +78,13 @@ impl<'w> EntityRef<'w> {
|
|||||||
|
|
||||||
/// Gets metadata indicating the location where the current entity is stored.
|
/// Gets metadata indicating the location where the current entity is stored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn location(&self) -> EntityLocation {
|
pub fn location(&self) -> EntityIdLocation {
|
||||||
self.cell.location()
|
self.cell.location()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the archetype that the current entity belongs to.
|
/// Returns the archetype that the current entity belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn archetype(&self) -> &Archetype {
|
pub fn archetype(&self) -> Option<&Archetype> {
|
||||||
self.cell.archetype()
|
self.cell.archetype()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,13 +488,13 @@ impl<'w> EntityMut<'w> {
|
|||||||
|
|
||||||
/// Gets metadata indicating the location where the current entity is stored.
|
/// Gets metadata indicating the location where the current entity is stored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn location(&self) -> EntityLocation {
|
pub fn location(&self) -> EntityIdLocation {
|
||||||
self.cell.location()
|
self.cell.location()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the archetype that the current entity belongs to.
|
/// Returns the archetype that the current entity belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn archetype(&self) -> &Archetype {
|
pub fn archetype(&self) -> Option<&Archetype> {
|
||||||
self.cell.archetype()
|
self.cell.archetype()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,37 +1123,34 @@ impl<'w> EntityWorldMut<'w> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
|
fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
|
||||||
let location = self.location();
|
|
||||||
let last_change_tick = self.world.last_change_tick;
|
let last_change_tick = self.world.last_change_tick;
|
||||||
let change_tick = self.world.read_change_tick();
|
let change_tick = self.world.read_change_tick();
|
||||||
UnsafeEntityCell::new(
|
UnsafeEntityCell::new(
|
||||||
self.world.as_unsafe_world_cell_readonly(),
|
self.world.as_unsafe_world_cell_readonly(),
|
||||||
self.entity,
|
self.entity,
|
||||||
location,
|
self.location,
|
||||||
last_change_tick,
|
last_change_tick,
|
||||||
change_tick,
|
change_tick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
|
fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
|
||||||
let location = self.location();
|
|
||||||
let last_change_tick = self.world.last_change_tick;
|
let last_change_tick = self.world.last_change_tick;
|
||||||
let change_tick = self.world.change_tick();
|
let change_tick = self.world.change_tick();
|
||||||
UnsafeEntityCell::new(
|
UnsafeEntityCell::new(
|
||||||
self.world.as_unsafe_world_cell(),
|
self.world.as_unsafe_world_cell(),
|
||||||
self.entity,
|
self.entity,
|
||||||
location,
|
self.location,
|
||||||
last_change_tick,
|
last_change_tick,
|
||||||
change_tick,
|
change_tick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
|
fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
|
||||||
let location = self.location();
|
|
||||||
let last_change_tick = self.world.last_change_tick;
|
let last_change_tick = self.world.last_change_tick;
|
||||||
let change_tick = self.world.change_tick();
|
let change_tick = self.world.change_tick();
|
||||||
UnsafeEntityCell::new(
|
UnsafeEntityCell::new(
|
||||||
self.world.as_unsafe_world_cell(),
|
self.world.as_unsafe_world_cell(),
|
||||||
self.entity,
|
self.entity,
|
||||||
location,
|
self.location,
|
||||||
last_change_tick,
|
last_change_tick,
|
||||||
change_tick,
|
change_tick,
|
||||||
)
|
)
|
||||||
@ -3275,13 +3272,13 @@ impl<'w> FilteredEntityRef<'w> {
|
|||||||
|
|
||||||
/// Gets metadata indicating the location where the current entity is stored.
|
/// Gets metadata indicating the location where the current entity is stored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn location(&self) -> EntityLocation {
|
pub fn location(&self) -> EntityIdLocation {
|
||||||
self.entity.location()
|
self.entity.location()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the archetype that the current entity belongs to.
|
/// Returns the archetype that the current entity belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn archetype(&self) -> &Archetype {
|
pub fn archetype(&self) -> Option<&Archetype> {
|
||||||
self.entity.archetype()
|
self.entity.archetype()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3617,13 +3614,13 @@ impl<'w> FilteredEntityMut<'w> {
|
|||||||
|
|
||||||
/// Gets metadata indicating the location where the current entity is stored.
|
/// Gets metadata indicating the location where the current entity is stored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn location(&self) -> EntityLocation {
|
pub fn location(&self) -> EntityIdLocation {
|
||||||
self.entity.location()
|
self.entity.location()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the archetype that the current entity belongs to.
|
/// Returns the archetype that the current entity belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn archetype(&self) -> &Archetype {
|
pub fn archetype(&self) -> Option<&Archetype> {
|
||||||
self.entity.archetype()
|
self.entity.archetype()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4928,7 +4925,10 @@ mod tests {
|
|||||||
let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
|
let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
|
||||||
|
|
||||||
world.entity_mut(ent).retain::<()>();
|
world.entity_mut(ent).retain::<()>();
|
||||||
assert_eq!(world.entity(ent).archetype().components().next(), None);
|
assert_eq!(
|
||||||
|
world.entity(ent).archetype().unwrap().components().next(),
|
||||||
|
None
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test removing some components with `retain`, including components not on the entity.
|
// Test removing some components with `retain`, including components not on the entity.
|
||||||
@ -4948,6 +4948,7 @@ mod tests {
|
|||||||
world
|
world
|
||||||
.entity(ent)
|
.entity(ent)
|
||||||
.archetype()
|
.archetype()
|
||||||
|
.unwrap()
|
||||||
.components()
|
.components()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.len(),
|
.len(),
|
||||||
|
|||||||
@ -977,7 +977,7 @@ impl World {
|
|||||||
let cell = UnsafeEntityCell::new(
|
let cell = UnsafeEntityCell::new(
|
||||||
self.as_unsafe_world_cell_readonly(),
|
self.as_unsafe_world_cell_readonly(),
|
||||||
entity,
|
entity,
|
||||||
location,
|
Some(location),
|
||||||
self.last_change_tick,
|
self.last_change_tick,
|
||||||
self.read_change_tick(),
|
self.read_change_tick(),
|
||||||
);
|
);
|
||||||
@ -1000,7 +1000,7 @@ impl World {
|
|||||||
let cell = UnsafeEntityCell::new(
|
let cell = UnsafeEntityCell::new(
|
||||||
world_cell,
|
world_cell,
|
||||||
entity,
|
entity,
|
||||||
location,
|
Some(location),
|
||||||
last_change_tick,
|
last_change_tick,
|
||||||
change_tick,
|
change_tick,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use crate::{
|
|||||||
component::{ComponentId, ComponentTicks, Components, Mutable, StorageType, Tick, TickCells},
|
component::{ComponentId, ComponentTicks, Components, Mutable, StorageType, Tick, TickCells},
|
||||||
entity::{
|
entity::{
|
||||||
ContainsEntity, Entities, EntitiesAllocator, Entity, EntityDoesNotExistError,
|
ContainsEntity, Entities, EntitiesAllocator, Entity, EntityDoesNotExistError,
|
||||||
EntityLocation,
|
EntityIdLocation, EntityLocation,
|
||||||
},
|
},
|
||||||
error::{DefaultErrorHandler, ErrorHandler},
|
error::{DefaultErrorHandler, ErrorHandler},
|
||||||
observer::Observers,
|
observer::Observers,
|
||||||
@ -375,7 +375,7 @@ impl<'w> UnsafeWorldCell<'w> {
|
|||||||
) -> Result<UnsafeEntityCell<'w>, EntityDoesNotExistError> {
|
) -> Result<UnsafeEntityCell<'w>, EntityDoesNotExistError> {
|
||||||
let location = self
|
let location = self
|
||||||
.entities()
|
.entities()
|
||||||
.get(entity)
|
.get_id_location(entity)
|
||||||
.ok_or(EntityDoesNotExistError::new(entity, self.entities()))?;
|
.ok_or(EntityDoesNotExistError::new(entity, self.entities()))?;
|
||||||
Ok(UnsafeEntityCell::new(
|
Ok(UnsafeEntityCell::new(
|
||||||
self,
|
self,
|
||||||
@ -397,7 +397,7 @@ impl<'w> UnsafeWorldCell<'w> {
|
|||||||
) -> Result<UnsafeEntityCell<'w>, EntityDoesNotExistError> {
|
) -> Result<UnsafeEntityCell<'w>, EntityDoesNotExistError> {
|
||||||
let location = self
|
let location = self
|
||||||
.entities()
|
.entities()
|
||||||
.get(entity)
|
.get_id_location(entity)
|
||||||
.ok_or(EntityDoesNotExistError::new(entity, self.entities()))?;
|
.ok_or(EntityDoesNotExistError::new(entity, self.entities()))?;
|
||||||
Ok(UnsafeEntityCell::new(
|
Ok(UnsafeEntityCell::new(
|
||||||
self, entity, location, last_run, this_run,
|
self, entity, location, last_run, this_run,
|
||||||
@ -743,7 +743,7 @@ impl Debug for UnsafeWorldCell<'_> {
|
|||||||
pub struct UnsafeEntityCell<'w> {
|
pub struct UnsafeEntityCell<'w> {
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
location: EntityLocation,
|
location: EntityIdLocation,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
}
|
}
|
||||||
@ -753,7 +753,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
location: EntityLocation,
|
location: EntityIdLocation,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -775,14 +775,15 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
|
|
||||||
/// Gets metadata indicating the location where the current entity is stored.
|
/// Gets metadata indicating the location where the current entity is stored.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn location(self) -> EntityLocation {
|
pub fn location(self) -> EntityIdLocation {
|
||||||
self.location
|
self.location
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the archetype that the current entity belongs to.
|
/// Returns the archetype that the current entity belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn archetype(self) -> &'w Archetype {
|
pub fn archetype(self) -> Option<&'w Archetype> {
|
||||||
&self.world.archetypes()[self.location.archetype_id]
|
self.location
|
||||||
|
.map(|loc| &self.world.archetypes()[loc.archetype_id])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the world that the current entity belongs to.
|
/// Gets the world that the current entity belongs to.
|
||||||
@ -813,7 +814,8 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
/// [`Self::contains_type_id`].
|
/// [`Self::contains_type_id`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains_id(self, component_id: ComponentId) -> bool {
|
pub fn contains_id(self, component_id: ComponentId) -> bool {
|
||||||
self.archetype().contains(component_id)
|
self.archetype()
|
||||||
|
.is_some_and(|archetype| archetype.contains(component_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
|
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
|
||||||
@ -848,7 +850,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
T::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
// SAFETY: returned component is of type T
|
// SAFETY: returned component is of type T
|
||||||
.map(|value| value.deref::<T>())
|
.map(|value| value.deref::<T>())
|
||||||
@ -875,7 +877,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
T::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
.map(|(value, cells, caller)| Ref {
|
.map(|(value, cells, caller)| Ref {
|
||||||
// SAFETY: returned component is of type T
|
// SAFETY: returned component is of type T
|
||||||
@ -906,7 +908,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
T::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -938,7 +940,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
info.storage_type(),
|
info.storage_type(),
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -991,7 +993,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
T::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
.map(|(value, cells, caller)| Mut {
|
.map(|(value, cells, caller)| Mut {
|
||||||
// SAFETY: returned component is of type T
|
// SAFETY: returned component is of type T
|
||||||
@ -1015,7 +1017,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
let world = self.world().world();
|
let world = self.world().world();
|
||||||
Q::get_state(world.components())?
|
Q::get_state(world.components())?
|
||||||
};
|
};
|
||||||
let location = self.location();
|
let location = self.location()?;
|
||||||
// SAFETY: Location is guaranteed to exist
|
// SAFETY: Location is guaranteed to exist
|
||||||
let archetype = unsafe {
|
let archetype = unsafe {
|
||||||
self.world
|
self.world
|
||||||
@ -1068,7 +1070,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
component_id,
|
component_id,
|
||||||
info.storage_type(),
|
info.storage_type(),
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1103,20 +1105,23 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
|
|
||||||
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
|
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
|
||||||
unsafe {
|
unsafe {
|
||||||
get_component_and_ticks(
|
self.location
|
||||||
self.world,
|
.and_then(|location| {
|
||||||
component_id,
|
get_component_and_ticks(
|
||||||
info.storage_type(),
|
self.world,
|
||||||
self.entity,
|
component_id,
|
||||||
self.location,
|
info.storage_type(),
|
||||||
)
|
self.entity,
|
||||||
.map(|(value, cells, caller)| MutUntyped {
|
location,
|
||||||
// SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
|
)
|
||||||
value: value.assert_unique(),
|
})
|
||||||
ticks: TicksMut::from_tick_cells(cells, self.last_run, self.this_run),
|
.map(|(value, cells, caller)| MutUntyped {
|
||||||
changed_by: caller.map(|caller| caller.deref_mut()),
|
// SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
|
||||||
})
|
value: value.assert_unique(),
|
||||||
.ok_or(GetEntityMutByIdError::ComponentNotFound)
|
ticks: TicksMut::from_tick_cells(cells, self.last_run, self.this_run),
|
||||||
|
changed_by: caller.map(|caller| caller.deref_mut()),
|
||||||
|
})
|
||||||
|
.ok_or(GetEntityMutByIdError::ComponentNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,20 +1152,23 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
|
|
||||||
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
|
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
|
||||||
unsafe {
|
unsafe {
|
||||||
get_component_and_ticks(
|
self.location
|
||||||
self.world,
|
.and_then(|location| {
|
||||||
component_id,
|
get_component_and_ticks(
|
||||||
info.storage_type(),
|
self.world,
|
||||||
self.entity,
|
component_id,
|
||||||
self.location,
|
info.storage_type(),
|
||||||
)
|
self.entity,
|
||||||
.map(|(value, cells, caller)| MutUntyped {
|
location,
|
||||||
// SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
|
)
|
||||||
value: value.assert_unique(),
|
})
|
||||||
ticks: TicksMut::from_tick_cells(cells, self.last_run, self.this_run),
|
.map(|(value, cells, caller)| MutUntyped {
|
||||||
changed_by: caller.map(|caller| caller.deref_mut()),
|
// SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
|
||||||
})
|
value: value.assert_unique(),
|
||||||
.ok_or(GetEntityMutByIdError::ComponentNotFound)
|
ticks: TicksMut::from_tick_cells(cells, self.last_run, self.this_run),
|
||||||
|
changed_by: caller.map(|caller| caller.deref_mut()),
|
||||||
|
})
|
||||||
|
.ok_or(GetEntityMutByIdError::ComponentNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1125,7 +1125,11 @@ pub fn process_remote_list_request(In(params): In<Option<Value>>, world: &World)
|
|||||||
// If `Some`, return all components of the provided entity.
|
// If `Some`, return all components of the provided entity.
|
||||||
if let Some(BrpListParams { entity }) = params.map(parse).transpose()? {
|
if let Some(BrpListParams { entity }) = params.map(parse).transpose()? {
|
||||||
let entity = get_entity(world, entity)?;
|
let entity = get_entity(world, entity)?;
|
||||||
for component_id in entity.archetype().components() {
|
for component_id in entity
|
||||||
|
.archetype()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|archetype| archetype.components())
|
||||||
|
{
|
||||||
let Some(component_info) = world.components().get_info(component_id) else {
|
let Some(component_info) = world.components().get_info(component_id) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@ -1179,7 +1183,11 @@ pub fn process_remote_list_watching_request(
|
|||||||
let entity_ref = get_entity(world, entity)?;
|
let entity_ref = get_entity(world, entity)?;
|
||||||
let mut response = BrpListWatchingResponse::default();
|
let mut response = BrpListWatchingResponse::default();
|
||||||
|
|
||||||
for component_id in entity_ref.archetype().components() {
|
for component_id in entity_ref
|
||||||
|
.archetype()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|archetype| archetype.components())
|
||||||
|
{
|
||||||
let ticks = entity_ref
|
let ticks = entity_ref
|
||||||
.get_change_ticks_by_id(component_id)
|
.get_change_ticks_by_id(component_id)
|
||||||
.ok_or(BrpError::internal("Failed to get ticks"))?;
|
.ok_or(BrpError::internal("Failed to get ticks"))?;
|
||||||
|
|||||||
@ -283,7 +283,11 @@ impl<'w> DynamicSceneBuilder<'w> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let original_entity = self.original_world.entity(entity);
|
let original_entity = self.original_world.entity(entity);
|
||||||
for component_id in original_entity.archetype().components() {
|
for component_id in original_entity
|
||||||
|
.archetype()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|archetype| archetype.components())
|
||||||
|
{
|
||||||
let mut extract_and_push = || {
|
let mut extract_and_push = || {
|
||||||
let type_id = self
|
let type_id = self
|
||||||
.original_world
|
.original_world
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user