Support non-Vec data structures in relations (#17447)
# Objective
The existing `RelationshipSourceCollection` uses `Vec` as the only
possible backing for our relationships. While a reasonable choice,
benchmarking use cases might reveal that a different data type is better
or faster.
For example:
- Not all relationships require a stable ordering between the
relationship sources (i.e. children). In cases where we a) have many
such relations and b) don't care about the ordering between them, a hash
set is likely a better datastructure than a `Vec`.
- The number of children-like entities may be small on average, and a
`smallvec` may be faster
## Solution
- Implement `RelationshipSourceCollection` for `EntityHashSet`, our
custom entity-optimized `HashSet`.
-~~Implement `DoubleEndedIterator` for `EntityHashSet` to make things
compile.~~
- This implementation was cursed and very surprising.
- Instead, by moving the iterator type on `RelationshipSourceCollection`
from an erased RPTIT to an explicit associated type we can add a trait
bound on the offending methods!
- Implement `RelationshipSourceCollection` for `SmallVec`
## Testing
I've added a pair of new tests to make sure this pattern compiles
successfully in practice!
## Migration Guide
`EntityHashSet` and `EntityHashMap` are no longer re-exported in
`bevy_ecs::entity` directly. If you were not using `bevy_ecs` / `bevy`'s
`prelude`, you can access them through their now-public modules,
`hash_set` and `hash_map` instead.
## Notes to reviewers
The `EntityHashSet::Iter` type needs to be public for this impl to be
allowed. I initially renamed it to something that wasn't ambiguous and
re-exported it, but as @Victoronz pointed out, that was somewhat
unidiomatic.
In
1a8564898f
,
I instead made the `entity_hash_set` public (and its `entity_hash_set`)
sister public, and removed the re-export. I prefer this design (give me
module docs please), but it leads to a lot of churn in this PR.
Let me know which you'd prefer, and if you'd like me to split that
change out into its own micro PR.
This commit is contained in:
parent
1dd30a620a
commit
5a9bc28502
@ -1,4 +1,4 @@
|
|||||||
use bevy_ecs::entity::{Entity, EntityHashSet};
|
use bevy_ecs::entity::{hash_set::EntityHashSet, Entity};
|
||||||
use criterion::{BenchmarkId, Criterion, Throughput};
|
use criterion::{BenchmarkId, Criterion, Throughput};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
@ -6,7 +6,7 @@ use bevy_app::Plugin;
|
|||||||
use bevy_asset::{load_internal_asset, Handle};
|
use bevy_asset::{load_internal_asset, Handle};
|
||||||
use bevy_derive::Deref;
|
use bevy_derive::Deref;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use bevy_image::BevyDefault as _;
|
use bevy_image::BevyDefault as _;
|
||||||
|
@ -125,7 +125,7 @@ derive_more = { version = "1", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
nonmax = { version = "0.5", default-features = false }
|
nonmax = { version = "0.5", default-features = false }
|
||||||
arrayvec = { version = "0.7.4", default-features = false, optional = true }
|
arrayvec = { version = "0.7.4", default-features = false, optional = true }
|
||||||
smallvec = { version = "1", features = ["union"] }
|
smallvec = { version = "1", features = ["union", "const_generics"] }
|
||||||
indexmap = { version = "2.5.0", default-features = false }
|
indexmap = { version = "2.5.0", default-features = false }
|
||||||
variadics_please = { version = "1.1", default-features = false }
|
variadics_please = { version = "1.1", default-features = false }
|
||||||
spin = { version = "0.9.8", default-features = false, features = [
|
spin = { version = "0.9.8", default-features = false, features = [
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
//! Contains the [`EntityHashMap`] type, a [`HashMap`] pre-configured to use [`EntityHash`] hashing.
|
||||||
|
//!
|
||||||
|
//! This module is a lightweight wrapper around [`hashbrown`](bevy_utils::hashbrown)'s [`HashMap`] that is more performant for [`Entity`] keys.
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
iter::FusedIterator,
|
iter::FusedIterator,
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
//! Contains the [`EntityHashSet`] type, a [`HashSet`] pre-configured to use [`EntityHash`] hashing.
|
||||||
|
//!
|
||||||
|
//! This module is a lightweight wrapper around [`hashbrown`](bevy_utils::hashbrown)'s [`HashSet`] that is more performant for [`Entity`] keys.
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
iter::FusedIterator,
|
iter::FusedIterator,
|
||||||
@ -38,6 +42,16 @@ impl EntityHashSet {
|
|||||||
Self(HashSet::with_capacity_and_hasher(n, EntityHash))
|
Self(HashSet::with_capacity_and_hasher(n, EntityHash))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of elements in the set.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.0.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the set contains no elements.
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the inner [`HashSet`].
|
/// Returns the inner [`HashSet`].
|
||||||
pub fn into_inner(self) -> HashSet<Entity, EntityHash> {
|
pub fn into_inner(self) -> HashSet<Entity, EntityHash> {
|
||||||
self.0
|
self.0
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{EntityHashMap, VisitEntitiesMut};
|
use super::{hash_map::EntityHashMap, VisitEntitiesMut};
|
||||||
|
|
||||||
/// Operation to map all contained [`Entity`] fields in a type to new values.
|
/// Operation to map all contained [`Entity`] fields in a type to new values.
|
||||||
///
|
///
|
||||||
@ -71,7 +71,7 @@ impl<T: VisitEntitiesMut> MapEntities for T {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ecs::entity::{Entity, EntityMapper};
|
/// # use bevy_ecs::entity::{Entity, EntityMapper};
|
||||||
/// # use bevy_ecs::entity::EntityHashMap;
|
/// # use bevy_ecs::entity::hash_map::EntityHashMap;
|
||||||
/// #
|
/// #
|
||||||
/// pub struct SimpleEntityMapper {
|
/// pub struct SimpleEntityMapper {
|
||||||
/// map: EntityHashMap<Entity>,
|
/// map: EntityHashMap<Entity>,
|
||||||
@ -194,7 +194,7 @@ impl<'m> SceneEntityMapper<'m> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
entity::{Entity, EntityHashMap, EntityMapper, SceneEntityMapper},
|
entity::{hash_map::EntityHashMap, Entity, EntityMapper, SceneEntityMapper},
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,11 +53,8 @@ pub use visit_entities::*;
|
|||||||
mod hash;
|
mod hash;
|
||||||
pub use hash::*;
|
pub use hash::*;
|
||||||
|
|
||||||
mod hash_map;
|
pub mod hash_map;
|
||||||
mod hash_set;
|
pub mod hash_set;
|
||||||
|
|
||||||
pub use hash_map::EntityHashMap;
|
|
||||||
pub use hash_set::EntityHashSet;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
archetype::{ArchetypeId, ArchetypeRow},
|
archetype::{ArchetypeId, ArchetypeRow},
|
||||||
|
@ -58,7 +58,7 @@ impl VisitEntitiesMut for Entity {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
self as bevy_ecs,
|
self as bevy_ecs,
|
||||||
entity::{EntityHashMap, MapEntities, SceneEntityMapper},
|
entity::{hash_map::EntityHashMap, MapEntities, SceneEntityMapper},
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
use alloc::{string::String, vec, vec::Vec};
|
use alloc::{string::String, vec, vec::Vec};
|
||||||
|
@ -9,7 +9,7 @@ pub use runner::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
archetype::ArchetypeFlags,
|
archetype::ArchetypeFlags,
|
||||||
component::ComponentId,
|
component::ComponentId,
|
||||||
entity::EntityHashMap,
|
entity::hash_map::EntityHashMap,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::IntoObserverSystem,
|
system::IntoObserverSystem,
|
||||||
world::{DeferredWorld, *},
|
world::{DeferredWorld, *},
|
||||||
|
@ -130,12 +130,22 @@ pub trait Relationship: Component + Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The iterator type for the source entities in a [`RelationshipTarget`] collection,
|
||||||
|
/// as defined in the [`RelationshipSourceCollection`] trait.
|
||||||
|
pub type SourceIter<'w, R> =
|
||||||
|
<<R as RelationshipTarget>::Collection as RelationshipSourceCollection>::SourceIter<'w>;
|
||||||
|
|
||||||
/// A [`Component`] containing the collection of entities that relate to this [`Entity`] via the associated `Relationship` type.
|
/// A [`Component`] containing the collection of entities that relate to this [`Entity`] via the associated `Relationship` type.
|
||||||
/// See the [`Relationship`] documentation for more information.
|
/// See the [`Relationship`] documentation for more information.
|
||||||
pub trait RelationshipTarget: Component<Mutability = Mutable> + Sized {
|
pub trait RelationshipTarget: Component<Mutability = Mutable> + Sized {
|
||||||
/// The [`Relationship`] that populates this [`RelationshipTarget`] collection.
|
/// The [`Relationship`] that populates this [`RelationshipTarget`] collection.
|
||||||
type Relationship: Relationship<RelationshipTarget = Self>;
|
type Relationship: Relationship<RelationshipTarget = Self>;
|
||||||
/// The collection type that stores the "source" entities for this [`RelationshipTarget`] component.
|
/// The collection type that stores the "source" entities for this [`RelationshipTarget`] component.
|
||||||
|
///
|
||||||
|
/// Check the list of types which implement [`RelationshipSourceCollection`] for the data structures that can be used inside of your component.
|
||||||
|
/// If you need a new collection type, you can implement the [`RelationshipSourceCollection`] trait
|
||||||
|
/// for a type you own which wraps the collection you want to use (to avoid the orphan rule),
|
||||||
|
/// or open an issue on the Bevy repository to request first-party support for your collection type.
|
||||||
type Collection: RelationshipSourceCollection;
|
type Collection: RelationshipSourceCollection;
|
||||||
|
|
||||||
/// Returns a reference to the stored [`RelationshipTarget::Collection`].
|
/// Returns a reference to the stored [`RelationshipTarget::Collection`].
|
||||||
@ -210,7 +220,7 @@ pub trait RelationshipTarget: Component<Mutability = Mutable> + Sized {
|
|||||||
|
|
||||||
/// Iterates the entities stored in this collection.
|
/// Iterates the entities stored in this collection.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter(&self) -> impl DoubleEndedIterator<Item = Entity> {
|
fn iter(&self) -> SourceIter<'_, Self> {
|
||||||
self.collection().iter()
|
self.collection().iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ use crate::{
|
|||||||
use alloc::collections::VecDeque;
|
use alloc::collections::VecDeque;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
use super::SourceIter;
|
||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||||
/// If the given `entity` contains the `R` [`Relationship`] component, returns the
|
/// If the given `entity` contains the `R` [`Relationship`] component, returns the
|
||||||
/// target entity of that relationship.
|
/// target entity of that relationship.
|
||||||
@ -59,6 +61,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
) -> impl Iterator<Item = Entity> + 'w
|
) -> impl Iterator<Item = Entity> + 'w
|
||||||
where
|
where
|
||||||
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
<D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||||
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
self.iter_descendants_depth_first(entity).filter(|entity| {
|
self.iter_descendants_depth_first(entity).filter(|entity| {
|
||||||
self.get(*entity)
|
self.get(*entity)
|
||||||
@ -114,6 +117,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
) -> DescendantDepthFirstIter<'w, 's, D, F, S>
|
) -> DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||||
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
DescendantDepthFirstIter::new(self, entity)
|
DescendantDepthFirstIter::new(self, entity)
|
||||||
}
|
}
|
||||||
@ -195,6 +199,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
|||||||
DescendantDepthFirstIter<'w, 's, D, F, S>
|
DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||||
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
/// Returns a new [`DescendantDepthFirstIter`].
|
/// Returns a new [`DescendantDepthFirstIter`].
|
||||||
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||||
@ -211,6 +216,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
|||||||
for DescendantDepthFirstIter<'w, 's, D, F, S>
|
for DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
D::ReadOnly: WorldQuery<Item<'w> = &'w S>,
|
||||||
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
type Item = Entity;
|
type Item = Entity;
|
||||||
|
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
use crate::entity::Entity;
|
use crate::entity::{hash_set::EntityHashSet, Entity};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
/// The internal [`Entity`] collection used by a [`RelationshipTarget`](crate::relationship::RelationshipTarget) component.
|
/// The internal [`Entity`] collection used by a [`RelationshipTarget`](crate::relationship::RelationshipTarget) component.
|
||||||
/// This is not intended to be modified directly by users, as it could invalidate the correctness of relationships.
|
/// This is not intended to be modified directly by users, as it could invalidate the correctness of relationships.
|
||||||
pub trait RelationshipSourceCollection {
|
pub trait RelationshipSourceCollection {
|
||||||
|
/// The type of iterator returned by the `iter` method.
|
||||||
|
///
|
||||||
|
/// This is an associated type (rather than using a method that returns an opaque return-position impl trait)
|
||||||
|
/// to ensure that all methods and traits (like [`DoubleEndedIterator`]) of the underlying collection's iterator
|
||||||
|
/// are available to the user when implemented without unduly restricting the possible collections.
|
||||||
|
///
|
||||||
|
/// The [`SourceIter`](super::SourceIter) type alias can be helpful to reduce confusion when working with this associated type.
|
||||||
|
type SourceIter<'a>: Iterator<Item = Entity>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
/// Returns an instance with the given pre-allocated entity `capacity`.
|
/// Returns an instance with the given pre-allocated entity `capacity`.
|
||||||
fn with_capacity(capacity: usize) -> Self;
|
fn with_capacity(capacity: usize) -> Self;
|
||||||
|
|
||||||
@ -14,7 +26,7 @@ pub trait RelationshipSourceCollection {
|
|||||||
fn remove(&mut self, entity: Entity);
|
fn remove(&mut self, entity: Entity);
|
||||||
|
|
||||||
/// Iterates all entities in the collection.
|
/// Iterates all entities in the collection.
|
||||||
fn iter(&self) -> impl DoubleEndedIterator<Item = Entity>;
|
fn iter(&self) -> Self::SourceIter<'_>;
|
||||||
|
|
||||||
/// Returns the current length of the collection.
|
/// Returns the current length of the collection.
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
@ -27,6 +39,8 @@ pub trait RelationshipSourceCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RelationshipSourceCollection for Vec<Entity> {
|
impl RelationshipSourceCollection for Vec<Entity> {
|
||||||
|
type SourceIter<'a> = core::iter::Copied<core::slice::Iter<'a, Entity>>;
|
||||||
|
|
||||||
fn with_capacity(capacity: usize) -> Self {
|
fn with_capacity(capacity: usize) -> Self {
|
||||||
Vec::with_capacity(capacity)
|
Vec::with_capacity(capacity)
|
||||||
}
|
}
|
||||||
@ -41,7 +55,7 @@ impl RelationshipSourceCollection for Vec<Entity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter(&self) -> impl DoubleEndedIterator<Item = Entity> {
|
fn iter(&self) -> Self::SourceIter<'_> {
|
||||||
<[Entity]>::iter(self).copied()
|
<[Entity]>::iter(self).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,3 +63,126 @@ impl RelationshipSourceCollection for Vec<Entity> {
|
|||||||
Vec::len(self)
|
Vec::len(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RelationshipSourceCollection for EntityHashSet {
|
||||||
|
type SourceIter<'a> = core::iter::Copied<crate::entity::hash_set::Iter<'a>>;
|
||||||
|
|
||||||
|
fn with_capacity(capacity: usize) -> Self {
|
||||||
|
EntityHashSet::with_capacity(capacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, entity: Entity) {
|
||||||
|
self.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, entity: Entity) {
|
||||||
|
// We need to call the remove method on the underlying hash set,
|
||||||
|
// which takes its argument by reference
|
||||||
|
self.0.remove(&entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter(&self) -> Self::SourceIter<'_> {
|
||||||
|
self.iter().copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
|
||||||
|
type SourceIter<'a> = core::iter::Copied<core::slice::Iter<'a, Entity>>;
|
||||||
|
|
||||||
|
fn with_capacity(capacity: usize) -> Self {
|
||||||
|
SmallVec::with_capacity(capacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, entity: Entity) {
|
||||||
|
SmallVec::push(self, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, entity: Entity) {
|
||||||
|
if let Some(index) = <[Entity]>::iter(self).position(|e| *e == entity) {
|
||||||
|
SmallVec::remove(self, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter(&self) -> Self::SourceIter<'_> {
|
||||||
|
<[Entity]>::iter(self).copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
SmallVec::len(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate as bevy_ecs;
|
||||||
|
use crate::prelude::{Component, World};
|
||||||
|
use crate::relationship::RelationshipTarget;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vec_relationship_source_collection() {
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship(relationship_target = RelTarget)]
|
||||||
|
struct Rel(Entity);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship_target(relationship = Rel, despawn_descendants)]
|
||||||
|
struct RelTarget(Vec<Entity>);
|
||||||
|
|
||||||
|
let mut world = World::new();
|
||||||
|
let a = world.spawn_empty().id();
|
||||||
|
let b = world.spawn_empty().id();
|
||||||
|
|
||||||
|
world.entity_mut(a).insert(Rel(b));
|
||||||
|
|
||||||
|
let rel_target = world.get::<RelTarget>(b).unwrap();
|
||||||
|
let collection = rel_target.collection();
|
||||||
|
assert_eq!(collection, &alloc::vec!(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn entity_hash_set_relationship_source_collection() {
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship(relationship_target = RelTarget)]
|
||||||
|
struct Rel(Entity);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship_target(relationship = Rel, despawn_descendants)]
|
||||||
|
struct RelTarget(EntityHashSet);
|
||||||
|
|
||||||
|
let mut world = World::new();
|
||||||
|
let a = world.spawn_empty().id();
|
||||||
|
let b = world.spawn_empty().id();
|
||||||
|
|
||||||
|
world.entity_mut(a).insert(Rel(b));
|
||||||
|
|
||||||
|
let rel_target = world.get::<RelTarget>(b).unwrap();
|
||||||
|
let collection = rel_target.collection();
|
||||||
|
assert_eq!(collection, &EntityHashSet::from([a]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn smallvec_relationship_source_collection() {
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship(relationship_target = RelTarget)]
|
||||||
|
struct Rel(Entity);
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[relationship_target(relationship = Rel, despawn_descendants)]
|
||||||
|
struct RelTarget(SmallVec<[Entity; 4]>);
|
||||||
|
|
||||||
|
let mut world = World::new();
|
||||||
|
let a = world.spawn_empty().id();
|
||||||
|
let b = world.spawn_empty().id();
|
||||||
|
|
||||||
|
world.entity_mut(a).insert(Rel(b));
|
||||||
|
|
||||||
|
let rel_target = world.get::<RelTarget>(b).unwrap();
|
||||||
|
let collection = rel_target.collection();
|
||||||
|
assert_eq!(collection, &SmallVec::from_buf([a]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -189,8 +189,8 @@ impl<'w> DeferredWorld<'w> {
|
|||||||
/// For examples, see [`DeferredWorld::entity_mut`].
|
/// For examples, see [`DeferredWorld::entity_mut`].
|
||||||
///
|
///
|
||||||
/// [`EntityMut`]: crate::world::EntityMut
|
/// [`EntityMut`]: crate::world::EntityMut
|
||||||
/// [`&EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`&EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
/// [`EntityHashMap<EntityMut>`]: crate::entity::EntityHashMap
|
/// [`EntityHashMap<EntityMut>`]: crate::entity::hash_map::EntityHashMap
|
||||||
/// [`Vec<EntityMut>`]: alloc::vec::Vec
|
/// [`Vec<EntityMut>`]: alloc::vec::Vec
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_entity_mut<F: WorldEntityFetch>(
|
pub fn get_entity_mut<F: WorldEntityFetch>(
|
||||||
@ -298,7 +298,7 @@ impl<'w> DeferredWorld<'w> {
|
|||||||
/// ## [`&EntityHashSet`]
|
/// ## [`&EntityHashSet`]
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ecs::{prelude::*, entity::EntityHashSet, world::DeferredWorld};
|
/// # use bevy_ecs::{prelude::*, entity::hash_set::EntityHashSet, world::DeferredWorld};
|
||||||
/// #[derive(Component)]
|
/// #[derive(Component)]
|
||||||
/// struct Position {
|
/// struct Position {
|
||||||
/// x: f32,
|
/// x: f32,
|
||||||
@ -321,8 +321,8 @@ impl<'w> DeferredWorld<'w> {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`EntityMut`]: crate::world::EntityMut
|
/// [`EntityMut`]: crate::world::EntityMut
|
||||||
/// [`&EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`&EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
/// [`EntityHashMap<EntityMut>`]: crate::entity::EntityHashMap
|
/// [`EntityHashMap<EntityMut>`]: crate::entity::hash_map::EntityHashMap
|
||||||
/// [`Vec<EntityMut>`]: alloc::vec::Vec
|
/// [`Vec<EntityMut>`]: alloc::vec::Vec
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::DeferredMut<'_> {
|
pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::DeferredMut<'_> {
|
||||||
|
@ -2,7 +2,7 @@ use alloc::vec::Vec;
|
|||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
entity::{Entity, EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet, Entity},
|
||||||
world::{
|
world::{
|
||||||
error::EntityFetchError, unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef,
|
error::EntityFetchError, unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef,
|
||||||
EntityWorldMut,
|
EntityWorldMut,
|
||||||
|
@ -647,10 +647,10 @@ impl World {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ## [`EntityHashSet`](crate::entity::EntityHashMap)
|
/// ## [`EntityHashSet`](crate::entity::hash_map::EntityHashMap)
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};
|
/// # use bevy_ecs::{prelude::*, entity::hash_set::EntityHashSet};
|
||||||
/// #[derive(Component)]
|
/// #[derive(Component)]
|
||||||
/// struct Position {
|
/// struct Position {
|
||||||
/// x: f32,
|
/// x: f32,
|
||||||
@ -668,7 +668,7 @@ impl World {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
#[inline]
|
#[inline]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {
|
pub fn entity<F: WorldEntityFetch>(&self, entities: F) -> F::Ref<'_> {
|
||||||
@ -699,8 +699,8 @@ impl World {
|
|||||||
/// such as adding or removing components, or despawning the entity.
|
/// such as adding or removing components, or despawning the entity.
|
||||||
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
|
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
|
||||||
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
|
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
|
||||||
/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
|
/// - Pass a reference to a [`EntityHashSet`](crate::entity::hash_map::EntityHashMap) to receive an
|
||||||
/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).
|
/// [`EntityHashMap<EntityMut>`](crate::entity::hash_map::EntityHashMap).
|
||||||
///
|
///
|
||||||
/// In order to perform structural changes on the returned entity reference,
|
/// In order to perform structural changes on the returned entity reference,
|
||||||
/// such as adding or removing components, or despawning the entity, only a
|
/// such as adding or removing components, or despawning the entity, only a
|
||||||
@ -781,10 +781,10 @@ impl World {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ## [`EntityHashSet`](crate::entity::EntityHashMap)
|
/// ## [`EntityHashSet`](crate::entity::hash_map::EntityHashMap)
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ecs::{prelude::*, entity::EntityHashSet};
|
/// # use bevy_ecs::{prelude::*, entity::hash_set::EntityHashSet};
|
||||||
/// #[derive(Component)]
|
/// #[derive(Component)]
|
||||||
/// struct Position {
|
/// struct Position {
|
||||||
/// x: f32,
|
/// x: f32,
|
||||||
@ -804,7 +804,7 @@ impl World {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
#[inline]
|
#[inline]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {
|
pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::Mut<'_> {
|
||||||
@ -853,8 +853,8 @@ impl World {
|
|||||||
/// - Pass an [`Entity`] to receive a single [`EntityRef`].
|
/// - Pass an [`Entity`] to receive a single [`EntityRef`].
|
||||||
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].
|
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].
|
||||||
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.
|
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.
|
||||||
/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
|
/// - Pass a reference to a [`EntityHashSet`](crate::entity::hash_map::EntityHashMap) to receive an
|
||||||
/// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).
|
/// [`EntityHashMap<EntityRef>`](crate::entity::hash_map::EntityHashMap).
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
@ -865,7 +865,7 @@ impl World {
|
|||||||
///
|
///
|
||||||
/// For examples, see [`World::entity`].
|
/// For examples, see [`World::entity`].
|
||||||
///
|
///
|
||||||
/// [`EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_entity<F: WorldEntityFetch>(&self, entities: F) -> Result<F::Ref<'_>, Entity> {
|
pub fn get_entity<F: WorldEntityFetch>(&self, entities: F) -> Result<F::Ref<'_>, Entity> {
|
||||||
let cell = self.as_unsafe_world_cell_readonly();
|
let cell = self.as_unsafe_world_cell_readonly();
|
||||||
@ -884,8 +884,8 @@ impl World {
|
|||||||
/// such as adding or removing components, or despawning the entity.
|
/// such as adding or removing components, or despawning the entity.
|
||||||
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
|
/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
|
||||||
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
|
/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
|
||||||
/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
|
/// - Pass a reference to a [`EntityHashSet`](crate::entity::hash_map::EntityHashMap) to receive an
|
||||||
/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).
|
/// [`EntityHashMap<EntityMut>`](crate::entity::hash_map::EntityHashMap).
|
||||||
///
|
///
|
||||||
/// In order to perform structural changes on the returned entity reference,
|
/// In order to perform structural changes on the returned entity reference,
|
||||||
/// such as adding or removing components, or despawning the entity, only a
|
/// such as adding or removing components, or despawning the entity, only a
|
||||||
@ -903,7 +903,7 @@ impl World {
|
|||||||
///
|
///
|
||||||
/// For examples, see [`World::entity_mut`].
|
/// For examples, see [`World::entity_mut`].
|
||||||
///
|
///
|
||||||
/// [`EntityHashSet`]: crate::entity::EntityHashSet
|
/// [`EntityHashSet`]: crate::entity::hash_set::EntityHashSet
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_entity_mut<F: WorldEntityFetch>(
|
pub fn get_entity_mut<F: WorldEntityFetch>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -3696,7 +3696,7 @@ mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
change_detection::DetectChangesMut,
|
change_detection::DetectChangesMut,
|
||||||
component::{ComponentDescriptor, ComponentInfo, StorageType},
|
component::{ComponentDescriptor, ComponentInfo, StorageType},
|
||||||
entity::EntityHashSet,
|
entity::hash_set::EntityHashSet,
|
||||||
ptr::OwningPtr,
|
ptr::OwningPtr,
|
||||||
system::Resource,
|
system::Resource,
|
||||||
world::error::EntityFetchError,
|
world::error::EntityFetchError,
|
||||||
|
@ -15,7 +15,7 @@ mod gilrs_system;
|
|||||||
mod rumble;
|
mod rumble;
|
||||||
|
|
||||||
use bevy_app::{App, Plugin, PostUpdate, PreStartup, PreUpdate};
|
use bevy_app::{App, Plugin, PostUpdate, PreStartup, PreUpdate};
|
||||||
use bevy_ecs::entity::EntityHashMap;
|
use bevy_ecs::entity::hash_map::EntityHashMap;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_input::InputSystem;
|
use bevy_input::InputSystem;
|
||||||
use bevy_utils::{synccell::SyncCell, HashMap};
|
use bevy_utils::{synccell::SyncCell, HashMap};
|
||||||
|
@ -10,7 +10,7 @@ use bevy_asset::{
|
|||||||
use bevy_color::{Color, LinearRgba};
|
use bevy_color::{Color, LinearRgba};
|
||||||
use bevy_core_pipeline::prelude::Camera3d;
|
use bevy_core_pipeline::prelude::Camera3d;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
hierarchy::ChildSpawner,
|
hierarchy::ChildSpawner,
|
||||||
name::Name,
|
name::Name,
|
||||||
world::World,
|
world::World,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemParam,
|
system::SystemParam,
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@ use core::num::NonZero;
|
|||||||
use bevy_core_pipeline::core_3d::Camera3d;
|
use bevy_core_pipeline::core_3d::Camera3d;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
query::{With, Without},
|
query::{With, Without},
|
||||||
reflect::ReflectComponent,
|
reflect::ReflectComponent,
|
||||||
system::{Commands, Query, Res, Resource},
|
system::{Commands, Query, Res, Resource},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::component::Component;
|
use bevy_ecs::component::Component;
|
||||||
use bevy_ecs::entity::{Entity, EntityHashMap};
|
use bevy_ecs::entity::{hash_map::EntityHashMap, Entity};
|
||||||
use bevy_ecs::reflect::ReflectComponent;
|
use bevy_ecs::reflect::ReflectComponent;
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||||
use bevy_render::sync_world::MainEntity;
|
use bevy_render::sync_world::MainEntity;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::ops::DerefMut;
|
use core::ops::DerefMut;
|
||||||
|
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use bevy_math::{ops, Mat4, Vec3A, Vec4};
|
use bevy_math::{ops, Mat4, Vec3A, Vec4};
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use bevy_asset::{AssetEvent, AssetServer, Assets, UntypedAssetId};
|
use bevy_asset::{AssetEvent, AssetServer, Assets, UntypedAssetId};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entities, Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entities, Entity},
|
||||||
event::EventReader,
|
event::EventReader,
|
||||||
query::Has,
|
query::Has,
|
||||||
system::{Local, Query, Res, ResMut, Resource, SystemState},
|
system::{Local, Query, Res, ResMut, Resource, SystemState},
|
||||||
|
@ -7,7 +7,7 @@ use bevy_core_pipeline::{
|
|||||||
};
|
};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
query::AnyOf,
|
query::AnyOf,
|
||||||
system::{Commands, Query, Res, ResMut, Resource},
|
system::{Commands, Query, Res, ResMut, Resource},
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ use bevy_color::ColorToComponents;
|
|||||||
use bevy_core_pipeline::core_3d::{Camera3d, CORE_3D_DEPTH_FORMAT};
|
use bevy_core_pipeline::core_3d::{Camera3d, CORE_3D_DEPTH_FORMAT};
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::lifetimeless::Read,
|
system::lifetimeless::Read,
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ use core::any::TypeId;
|
|||||||
|
|
||||||
use bevy_app::{App, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
query::{Has, With},
|
query::{Has, With},
|
||||||
schedule::IntoSystemConfigs as _,
|
schedule::IntoSystemConfigs as _,
|
||||||
system::{Query, Res, ResMut, Resource, StaticSystemParam},
|
system::{Query, Res, ResMut, Resource, StaticSystemParam},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
|
|
||||||
use bevy_ecs::{component::Component, entity::EntityHashMap, reflect::ReflectComponent};
|
use bevy_ecs::{component::Component, entity::hash_map::EntityHashMap, reflect::ReflectComponent};
|
||||||
use bevy_math::{Affine3A, Mat3A, Mat4, Vec3, Vec3A, Vec4, Vec4Swizzles};
|
use bevy_math::{Affine3A, Mat3A, Mat4, Vec3, Vec3A, Vec4, Vec4Swizzles};
|
||||||
use bevy_reflect::prelude::*;
|
use bevy_reflect::prelude::*;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ mod render_layers;
|
|||||||
use core::any::TypeId;
|
use core::any::TypeId;
|
||||||
|
|
||||||
use bevy_ecs::component::ComponentId;
|
use bevy_ecs::component::ComponentId;
|
||||||
use bevy_ecs::entity::EntityHashSet;
|
use bevy_ecs::entity::hash_set::EntityHashSet;
|
||||||
use bevy_ecs::world::DeferredWorld;
|
use bevy_ecs::world::DeferredWorld;
|
||||||
use derive_more::derive::{Deref, DerefMut};
|
use derive_more::derive::{Deref, DerefMut};
|
||||||
pub use range::*;
|
pub use range::*;
|
||||||
|
@ -9,7 +9,7 @@ use core::{
|
|||||||
use bevy_app::{App, Plugin, PostUpdate};
|
use bevy_app::{App, Plugin, PostUpdate};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
query::{Changed, With},
|
query::{Changed, With},
|
||||||
reflect::ReflectComponent,
|
reflect::ReflectComponent,
|
||||||
removal_detection::RemovedComponents,
|
removal_detection::RemovedComponents,
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
Extract, ExtractSchedule, Render, RenderApp, RenderSet, WgpuWrapper,
|
Extract, ExtractSchedule, Render, RenderApp, RenderSet, WgpuWrapper,
|
||||||
};
|
};
|
||||||
use bevy_app::{App, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::{entity::EntityHashMap, prelude::*};
|
use bevy_ecs::{entity::hash_map::EntityHashMap, prelude::*};
|
||||||
use bevy_utils::{default, HashSet};
|
use bevy_utils::{default, HashSet};
|
||||||
use bevy_window::{
|
use bevy_window::{
|
||||||
CompositeAlphaMode, PresentMode, PrimaryWindow, RawHandleWrapper, Window, WindowClosing,
|
CompositeAlphaMode, PresentMode, PrimaryWindow, RawHandleWrapper, Window, WindowClosing,
|
||||||
|
@ -20,7 +20,7 @@ use bevy_app::{First, Plugin, Update};
|
|||||||
use bevy_asset::{load_internal_asset, Handle};
|
use bevy_asset::{load_internal_asset, Handle};
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::EntityHashMap, event::event_update_system, prelude::*, system::SystemState,
|
entity::hash_map::EntityHashMap, event::event_update_system, prelude::*, system::SystemState,
|
||||||
};
|
};
|
||||||
use bevy_image::{Image, TextureFormatPixelInfo};
|
use bevy_image::{Image, TextureFormatPixelInfo};
|
||||||
use bevy_reflect::Reflect;
|
use bevy_reflect::Reflect;
|
||||||
|
@ -2,7 +2,7 @@ use crate::{ron, DynamicSceneBuilder, Scene, SceneSpawnError};
|
|||||||
use bevy_asset::Asset;
|
use bevy_asset::Asset;
|
||||||
use bevy_ecs::reflect::ReflectResource;
|
use bevy_ecs::reflect::ReflectResource;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap, SceneEntityMapper},
|
entity::{hash_map::EntityHashMap, Entity, SceneEntityMapper},
|
||||||
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities},
|
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities},
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
@ -200,7 +200,8 @@ mod tests {
|
|||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::{
|
entity::{
|
||||||
Entity, EntityHashMap, EntityMapper, MapEntities, VisitEntities, VisitEntitiesMut,
|
hash_map::EntityHashMap, Entity, EntityMapper, MapEntities, VisitEntities,
|
||||||
|
VisitEntitiesMut,
|
||||||
},
|
},
|
||||||
hierarchy::Parent,
|
hierarchy::Parent,
|
||||||
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
|
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{DynamicScene, SceneSpawnError};
|
use crate::{DynamicScene, SceneSpawnError};
|
||||||
use bevy_asset::Asset;
|
use bevy_asset::Asset;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap, SceneEntityMapper},
|
entity::{hash_map::EntityHashMap, Entity, SceneEntityMapper},
|
||||||
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
|
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{DynamicScene, Scene};
|
use crate::{DynamicScene, Scene};
|
||||||
use bevy_asset::{AssetEvent, AssetId, Assets, Handle};
|
use bevy_asset::{AssetEvent, AssetId, Assets, Handle};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
event::{Event, EventCursor, Events},
|
event::{Event, EventCursor, Events},
|
||||||
hierarchy::Parent,
|
hierarchy::Parent,
|
||||||
reflect::AppTypeRegistry,
|
reflect::AppTypeRegistry,
|
||||||
|
@ -515,7 +515,7 @@ mod tests {
|
|||||||
DynamicScene, DynamicSceneBuilder,
|
DynamicScene, DynamicSceneBuilder,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap, VisitEntities, VisitEntitiesMut},
|
entity::{hash_map::EntityHashMap, Entity, VisitEntities, VisitEntitiesMut},
|
||||||
prelude::{Component, ReflectComponent, ReflectResource, Resource, World},
|
prelude::{Component, ReflectComponent, ReflectResource, Resource, World},
|
||||||
query::{With, Without},
|
query::{With, Without},
|
||||||
reflect::{AppTypeRegistry, ReflectMapEntities},
|
reflect::{AppTypeRegistry, ReflectMapEntities},
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use bevy_color::LinearRgba;
|
use bevy_color::LinearRgba;
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::entity::EntityHashSet;
|
use bevy_ecs::entity::hash_set::EntityHashSet;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::{DetectChanges, Ref},
|
change_detection::{DetectChanges, Ref},
|
||||||
component::{require, Component},
|
component::{require, Component},
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
OverflowAxis, ScrollPosition, UiScale, UiTargetCamera, Val,
|
OverflowAxis, ScrollPosition, UiScale, UiTargetCamera, Val,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{EntityHashMap, EntityHashSet},
|
entity::{hash_map::EntityHashMap, hash_set::EntityHashSet},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
system::SystemParam,
|
system::SystemParam,
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ use core::fmt;
|
|||||||
use taffy::TaffyTree;
|
use taffy::TaffyTree;
|
||||||
|
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
prelude::Resource,
|
prelude::Resource,
|
||||||
};
|
};
|
||||||
use bevy_math::{UVec2, Vec2};
|
use bevy_math::{UVec2, Vec2};
|
||||||
|
@ -18,7 +18,7 @@ use bevy_color::{Alpha, ColorToComponents, LinearRgba};
|
|||||||
use bevy_core_pipeline::core_2d::graph::{Core2d, Node2d};
|
use bevy_core_pipeline::core_2d::graph::{Core2d, Node2d};
|
||||||
use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d};
|
use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d};
|
||||||
use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
|
use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
|
||||||
use bevy_ecs::entity::EntityHashMap;
|
use bevy_ecs::entity::hash_map::EntityHashMap;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_image::prelude::*;
|
use bevy_image::prelude::*;
|
||||||
use bevy_math::{FloatOrd, Mat4, Rect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles};
|
use bevy_math::{FloatOrd, Mat4, Rect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles};
|
||||||
|
@ -7,7 +7,7 @@ use bevy_color::Color;
|
|||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::DetectChanges,
|
change_detection::DetectChanges,
|
||||||
entity::{Entity, EntityHashMap},
|
entity::{hash_map::EntityHashMap, Entity},
|
||||||
prelude::{require, Component},
|
prelude::{require, Component},
|
||||||
query::With,
|
query::With,
|
||||||
reflect::ReflectComponent,
|
reflect::ReflectComponent,
|
||||||
|
@ -15,7 +15,7 @@ use bevy_a11y::{
|
|||||||
};
|
};
|
||||||
use bevy_app::{App, Plugin, PostUpdate};
|
use bevy_app::{App, Plugin, PostUpdate};
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
use bevy_ecs::{entity::EntityHashMap, prelude::*};
|
use bevy_ecs::{entity::hash_map::EntityHashMap, prelude::*};
|
||||||
use bevy_window::{PrimaryWindow, Window, WindowClosed};
|
use bevy_window::{PrimaryWindow, Window, WindowClosed};
|
||||||
|
|
||||||
/// Maps window entities to their `AccessKit` [`Adapter`]s.
|
/// Maps window entities to their `AccessKit` [`Adapter`]s.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use bevy_a11y::AccessibilityRequested;
|
use bevy_a11y::AccessibilityRequested;
|
||||||
use bevy_ecs::entity::Entity;
|
use bevy_ecs::entity::Entity;
|
||||||
|
|
||||||
use bevy_ecs::entity::EntityHashMap;
|
use bevy_ecs::entity::hash_map::EntityHashMap;
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
use bevy_window::{
|
use bevy_window::{
|
||||||
CursorGrabMode, MonitorSelection, Window, WindowMode, WindowPosition, WindowResolution,
|
CursorGrabMode, MonitorSelection, Window, WindowMode, WindowPosition, WindowResolution,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
//! Control animations of entities in the loaded scene.
|
//! Control animations of entities in the loaded scene.
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use bevy::{animation::AnimationTarget, ecs::entity::EntityHashMap, gltf::Gltf, prelude::*};
|
use bevy::{
|
||||||
|
animation::AnimationTarget, ecs::entity::hash_map::EntityHashMap, gltf::Gltf, prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::scene_viewer_plugin::SceneHandle;
|
use crate::scene_viewer_plugin::SceneHandle;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user