1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
#[cfg(feature = "reflect")]
use bevy_ecs::reflect::{ReflectComponent, ReflectMapEntities};
use bevy_ecs::{
component::Component,
entity::{Entity, EntityMapper, MapEntities},
prelude::FromWorld,
world::World,
};
use core::slice;
use smallvec::SmallVec;
use std::ops::Deref;
/// Contains references to the child entities of this entity.
///
/// Each child must contain a [`Parent`] component that points back to this entity.
/// This component rarely needs to be created manually,
/// consider using higher level utilities like [`BuildChildren::with_children`]
/// which are safer and easier to use.
///
/// See [`HierarchyQueryExt`] for hierarchy related methods on [`Query`].
///
/// [`HierarchyQueryExt`]: crate::query_extension::HierarchyQueryExt
/// [`Query`]: bevy_ecs::system::Query
/// [`Parent`]: crate::components::parent::Parent
/// [`BuildChildren::with_children`]: crate::child_builder::BuildChildren::with_children
#[derive(Component, Debug)]
#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
#[cfg_attr(feature = "reflect", reflect(Component, MapEntities))]
pub struct Children(pub(crate) SmallVec<[Entity; 8]>);
impl MapEntities for Children {
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
for entity in &mut self.0 {
*entity = entity_mapper.map_entity(*entity);
}
}
}
// TODO: We need to impl either FromWorld or Default so Children can be registered as Reflect.
// This is because Reflect deserialize by creating an instance and apply a patch on top.
// However Children should only ever be set with a real user-defined entities. Its worth looking
// into better ways to handle cases like this.
impl FromWorld for Children {
#[inline]
fn from_world(_world: &mut World) -> Self {
Children(SmallVec::new())
}
}
impl Children {
/// Constructs a [`Children`] component with the given entities.
#[inline]
pub(crate) fn from_entities(entities: &[Entity]) -> Self {
Self(SmallVec::from_slice(entities))
}
/// Swaps the child at `a_index` with the child at `b_index`.
#[inline]
pub fn swap(&mut self, a_index: usize, b_index: usize) {
self.0.swap(a_index, b_index);
}
/// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
/// in place using the provided comparator function.
///
/// For the underlying implementation, see [`slice::sort_by`].
///
/// For the unstable version, see [`sort_unstable_by`](Children::sort_unstable_by).
///
/// See also [`sort_by_key`](Children::sort_by_key), [`sort_by_cached_key`](Children::sort_by_cached_key).
#[inline]
pub fn sort_by<F>(&mut self, compare: F)
where
F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
{
self.0.sort_by(compare);
}
/// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
/// in place using the provided key extraction function.
///
/// For the underlying implementation, see [`slice::sort_by_key`].
///
/// For the unstable version, see [`sort_unstable_by_key`](Children::sort_unstable_by_key).
///
/// See also [`sort_by`](Children::sort_by), [`sort_by_cached_key`](Children::sort_by_cached_key).
#[inline]
pub fn sort_by_key<K, F>(&mut self, compare: F)
where
F: FnMut(&Entity) -> K,
K: Ord,
{
self.0.sort_by_key(compare);
}
/// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
/// in place using the provided key extraction function. Only evaluates each key at most
/// once per sort, caching the intermediate results in memory.
///
/// For the underlying implementation, see [`slice::sort_by_cached_key`].
///
/// See also [`sort_by`](Children::sort_by), [`sort_by_key`](Children::sort_by_key).
#[inline]
pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
where
F: FnMut(&Entity) -> K,
K: Ord,
{
self.0.sort_by_cached_key(compare);
}
/// Sorts children [unstably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
/// in place using the provided comparator function.
///
/// For the underlying implementation, see [`slice::sort_unstable_by`].
///
/// For the stable version, see [`sort_by`](Children::sort_by).
///
/// See also [`sort_unstable_by_key`](Children::sort_unstable_by_key).
#[inline]
pub fn sort_unstable_by<F>(&mut self, compare: F)
where
F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
{
self.0.sort_unstable_by(compare);
}
/// Sorts children [unstably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
/// in place using the provided key extraction function.
///
/// For the underlying implementation, see [`slice::sort_unstable_by_key`].
///
/// For the stable version, see [`sort_by_key`](Children::sort_by_key).
///
/// See also [`sort_unstable_by`](Children::sort_unstable_by).
#[inline]
pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
where
F: FnMut(&Entity) -> K,
K: Ord,
{
self.0.sort_unstable_by_key(compare);
}
}
impl Deref for Children {
type Target = [Entity];
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0[..]
}
}
impl<'a> IntoIterator for &'a Children {
type Item = <Self::IntoIter as Iterator>::Item;
type IntoIter = slice::Iter<'a, Entity>;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}