mirror of
https://github.com/bevyengine/bevy
synced 2024-11-23 05:03:47 +00:00
Document every public item in bevy_ecs
(#8731)
# Objective Title. --------- Co-authored-by: François <mockersf@gmail.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: James Liu <contact@jamessliu.com>
This commit is contained in:
parent
50bc785c8a
commit
32faf4cb5c
41 changed files with 374 additions and 14 deletions
|
@ -44,6 +44,8 @@ use std::{
|
|||
pub struct ArchetypeRow(u32);
|
||||
|
||||
impl ArchetypeRow {
|
||||
/// Index indicating an invalid archetype row.
|
||||
/// This is meant to be used as a placeholder.
|
||||
pub const INVALID: ArchetypeRow = ArchetypeRow(u32::MAX);
|
||||
|
||||
/// Creates a `ArchetypeRow`.
|
||||
|
@ -349,6 +351,7 @@ impl Archetype {
|
|||
self.table_id
|
||||
}
|
||||
|
||||
/// Fetches the entities contained in this archetype.
|
||||
#[inline]
|
||||
pub fn entities(&self) -> &[ArchetypeEntity] {
|
||||
&self.entities
|
||||
|
@ -614,6 +617,8 @@ impl Archetypes {
|
|||
archetypes
|
||||
}
|
||||
|
||||
/// Returns the current archetype generation. This is an ID indicating the current set of archetypes
|
||||
/// that are registered with the world.
|
||||
#[inline]
|
||||
pub fn generation(&self) -> ArchetypeGeneration {
|
||||
ArchetypeGeneration(self.archetypes.len())
|
||||
|
@ -719,6 +724,8 @@ impl Archetypes {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns the number of components that are stored in archetypes.
|
||||
/// Note that if some component `T` is stored in more than one archetype, it will be counted once for each archetype it's present in.
|
||||
#[inline]
|
||||
pub fn archetype_components_len(&self) -> usize {
|
||||
self.archetype_component_count
|
||||
|
|
|
@ -247,10 +247,16 @@ macro_rules! tuple_impl {
|
|||
|
||||
all_tuples!(tuple_impl, 0, 15, B);
|
||||
|
||||
/// For a specific [`World`], this stores a unique value identifying a type of a registered [`Bundle`].
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct BundleId(usize);
|
||||
|
||||
impl BundleId {
|
||||
/// Returns the index of the associated [`Bundle`] type.
|
||||
///
|
||||
/// Note that this is unique per-world, and should not be reused across them.
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
|
@ -269,6 +275,9 @@ impl SparseSetIndex for BundleId {
|
|||
}
|
||||
}
|
||||
|
||||
/// Stores metadata associated with a specific type of [`Bundle`] for a given [`World`].
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
pub struct BundleInfo {
|
||||
id: BundleId,
|
||||
// SAFETY: Every ID in this list must be valid within the World that owns the BundleInfo,
|
||||
|
@ -324,11 +333,13 @@ impl BundleInfo {
|
|||
BundleInfo { id, component_ids }
|
||||
}
|
||||
|
||||
/// Returns a value identifying the associated [`Bundle`] type.
|
||||
#[inline]
|
||||
pub const fn id(&self) -> BundleId {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// Returns the [ID](ComponentId) of each component stored in this bundle.
|
||||
#[inline]
|
||||
pub fn components(&self) -> &[ComponentId] {
|
||||
&self.component_ids
|
||||
|
@ -782,6 +793,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Metadata for bundles. Stores a [`BundleInfo`] for each type of [`Bundle`] in a given world.
|
||||
#[derive(Default)]
|
||||
pub struct Bundles {
|
||||
bundle_infos: Vec<BundleInfo>,
|
||||
|
@ -794,11 +806,16 @@ pub struct Bundles {
|
|||
}
|
||||
|
||||
impl Bundles {
|
||||
/// Gets the metadata associated with a specific type of bundle.
|
||||
/// Returns `None` if the bundle is not registered with the world.
|
||||
#[inline]
|
||||
pub fn get(&self, bundle_id: BundleId) -> Option<&BundleInfo> {
|
||||
self.bundle_infos.get(bundle_id.index())
|
||||
}
|
||||
|
||||
/// Gets the value identifying a specific type of bundle.
|
||||
/// Returns `None` if the bundle does not exist in the world,
|
||||
/// or if `type_id` does not correspond to a type of bundle.
|
||||
#[inline]
|
||||
pub fn get_id(&self, type_id: TypeId) -> Option<BundleId> {
|
||||
self.bundle_ids.get(&type_id).cloned()
|
||||
|
|
|
@ -401,7 +401,10 @@ pub struct Res<'w, T: ?Sized + Resource> {
|
|||
}
|
||||
|
||||
impl<'w, T: Resource> Res<'w, T> {
|
||||
// no it shouldn't clippy
|
||||
/// Copies a reference to a resource.
|
||||
///
|
||||
/// Note that unless you actually need an instance of `Res<T>`, you should
|
||||
/// prefer to just convert it to `&T` which can be freely copied.
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn clone(this: &Self) -> Self {
|
||||
Self {
|
||||
|
@ -539,6 +542,7 @@ pub struct Ref<'a, T: ?Sized> {
|
|||
}
|
||||
|
||||
impl<'a, T: ?Sized> Ref<'a, T> {
|
||||
/// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.
|
||||
pub fn into_inner(self) -> &'a T {
|
||||
self.value
|
||||
}
|
||||
|
|
|
@ -146,14 +146,23 @@ use std::{
|
|||
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
|
||||
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
|
||||
pub trait Component: Send + Sync + 'static {
|
||||
/// A marker type indicating the storage type used for this component.
|
||||
/// This must be either [`TableStorage`] or [`SparseStorage`].
|
||||
type Storage: ComponentStorage;
|
||||
}
|
||||
|
||||
/// Marker type for components stored in a [`Table`](crate::storage::Table).
|
||||
pub struct TableStorage;
|
||||
|
||||
/// Marker type for components stored in a [`ComponentSparseSet`](crate::storage::ComponentSparseSet).
|
||||
pub struct SparseStorage;
|
||||
|
||||
/// Types used to specify the storage strategy for a component.
|
||||
///
|
||||
/// This trait is implemented for [`TableStorage`] and [`SparseStorage`].
|
||||
/// Custom implementations are forbidden.
|
||||
pub trait ComponentStorage: sealed::Sealed {
|
||||
// because the trait is sealed, those items are private API.
|
||||
/// A value indicating the storage strategy specified by this type.
|
||||
const STORAGE_TYPE: StorageType;
|
||||
}
|
||||
|
||||
|
@ -191,6 +200,7 @@ pub enum StorageType {
|
|||
SparseSet,
|
||||
}
|
||||
|
||||
/// Stores metadata for a type of component or resource stored in a specific [`World`].
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentInfo {
|
||||
id: ComponentId,
|
||||
|
@ -198,21 +208,26 @@ pub struct ComponentInfo {
|
|||
}
|
||||
|
||||
impl ComponentInfo {
|
||||
/// Returns a value uniquely identifying the current component.
|
||||
#[inline]
|
||||
pub fn id(&self) -> ComponentId {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// Returns the name of the current component.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &str {
|
||||
&self.descriptor.name
|
||||
}
|
||||
|
||||
/// Returns the [`TypeId`] of the underlying component type.
|
||||
/// Returns `None` if the component does not correspond to a Rust type.
|
||||
#[inline]
|
||||
pub fn type_id(&self) -> Option<TypeId> {
|
||||
self.descriptor.type_id
|
||||
}
|
||||
|
||||
/// Returns the layout used to store values of this component in memory.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> Layout {
|
||||
self.descriptor.layout
|
||||
|
@ -229,11 +244,15 @@ impl ComponentInfo {
|
|||
self.descriptor.drop
|
||||
}
|
||||
|
||||
/// Returns a value indicating the storage strategy for the current component.
|
||||
#[inline]
|
||||
pub fn storage_type(&self) -> StorageType {
|
||||
self.descriptor.storage_type
|
||||
}
|
||||
|
||||
/// Returns `true` if the underlying component type can be freely shared between threads.
|
||||
/// If this returns `false`, then extra care must be taken to ensure that components
|
||||
/// are not accessed from the wrong thread.
|
||||
#[inline]
|
||||
pub fn is_send_and_sync(&self) -> bool {
|
||||
self.descriptor.is_send_and_sync
|
||||
|
@ -245,7 +264,7 @@ impl ComponentInfo {
|
|||
}
|
||||
}
|
||||
|
||||
/// A semi-opaque value which uniquely identifies the type of a [`Component`] within a
|
||||
/// A value which uniquely identifies the type of a [`Component`] within a
|
||||
/// [`World`](crate::world::World).
|
||||
///
|
||||
/// Each time a new `Component` type is registered within a `World` using
|
||||
|
@ -266,11 +285,16 @@ impl ComponentInfo {
|
|||
pub struct ComponentId(usize);
|
||||
|
||||
impl ComponentId {
|
||||
/// Creates a new [`ComponentId`].
|
||||
///
|
||||
/// The `index` is a unique value associated with each type of component in a given world.
|
||||
/// Usually, this value is taken from a counter incremented for each type of component registered with the world.
|
||||
#[inline]
|
||||
pub const fn new(index: usize) -> ComponentId {
|
||||
ComponentId(index)
|
||||
}
|
||||
|
||||
/// Returns the index of the current component.
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
|
@ -289,6 +313,7 @@ impl SparseSetIndex for ComponentId {
|
|||
}
|
||||
}
|
||||
|
||||
/// A value describing a component or resource, which may or may not correspond to a Rust type.
|
||||
pub struct ComponentDescriptor {
|
||||
name: Cow<'static, str>,
|
||||
// SAFETY: This must remain private. It must match the statically known StorageType of the
|
||||
|
@ -384,22 +409,27 @@ impl ComponentDescriptor {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a value indicating the storage strategy for the current component.
|
||||
#[inline]
|
||||
pub fn storage_type(&self) -> StorageType {
|
||||
self.storage_type
|
||||
}
|
||||
|
||||
/// Returns the [`TypeId`] of the underlying component type.
|
||||
/// Returns `None` if the component does not correspond to a Rust type.
|
||||
#[inline]
|
||||
pub fn type_id(&self) -> Option<TypeId> {
|
||||
self.type_id
|
||||
}
|
||||
|
||||
/// Returns the name of the current component.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &str {
|
||||
self.name.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores metadata associated with each kind of [`Component`] in a given [`World`].
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Components {
|
||||
components: Vec<ComponentInfo>,
|
||||
|
@ -408,6 +438,9 @@ pub struct Components {
|
|||
}
|
||||
|
||||
impl Components {
|
||||
/// Initializes a component of type `T` with this instance.
|
||||
/// If a component of this type has already been initialized, this will return
|
||||
/// the ID of the pre-existing component.
|
||||
#[inline]
|
||||
pub fn init_component<T: Component>(&mut self, storages: &mut Storages) -> ComponentId {
|
||||
let type_id = TypeId::of::<T>();
|
||||
|
@ -423,6 +456,12 @@ impl Components {
|
|||
ComponentId(*index)
|
||||
}
|
||||
|
||||
/// Initializes a component described by `descriptor`.
|
||||
///
|
||||
/// ## Note
|
||||
///
|
||||
/// If this method is called multiple times with identical descriptors, a distinct `ComponentId`
|
||||
/// will be created for each one.
|
||||
pub fn init_component_with_descriptor(
|
||||
&mut self,
|
||||
storages: &mut Storages,
|
||||
|
@ -447,26 +486,35 @@ impl Components {
|
|||
index
|
||||
}
|
||||
|
||||
/// Returns the number of components registered with this instance.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.components.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if there are no components registered with this instance. Otherwise, this returns `false`.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.components.len() == 0
|
||||
}
|
||||
|
||||
/// Gets the metadata associated with the given component.
|
||||
///
|
||||
/// This will return an incorrect result if `id` did not come from the same world as `self`. It may return `None` or a garbage value.
|
||||
#[inline]
|
||||
pub fn get_info(&self, id: ComponentId) -> Option<&ComponentInfo> {
|
||||
self.components.get(id.0)
|
||||
}
|
||||
|
||||
/// Returns the name associated with the given component.
|
||||
///
|
||||
/// This will return an incorrect result if `id` did not come from the same world as `self`. It may return `None` or a garbage value.
|
||||
#[inline]
|
||||
pub fn get_name(&self, id: ComponentId) -> Option<&str> {
|
||||
self.get_info(id).map(|descriptor| descriptor.name())
|
||||
}
|
||||
|
||||
/// Gets the metadata associated with the given component.
|
||||
/// # Safety
|
||||
///
|
||||
/// `id` must be a valid [`ComponentId`]
|
||||
|
@ -542,6 +590,9 @@ impl Components {
|
|||
self.get_resource_id(TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Initializes a [`Resource`] of type `T` with this instance.
|
||||
/// If a resource of this type has already been initialized, this will return
|
||||
/// the ID of the pre-existing resource.
|
||||
#[inline]
|
||||
pub fn init_resource<T: Resource>(&mut self) -> ComponentId {
|
||||
// SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`]
|
||||
|
@ -552,6 +603,9 @@ impl Components {
|
|||
}
|
||||
}
|
||||
|
||||
/// Initializes a [non-send resource](crate::system::NonSend) of type `T` with this instance.
|
||||
/// If a resource of this type has already been initialized, this will return
|
||||
/// the ID of the pre-existing resource.
|
||||
#[inline]
|
||||
pub fn init_non_send<T: Any>(&mut self) -> ComponentId {
|
||||
// SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`]
|
||||
|
@ -582,6 +636,7 @@ impl Components {
|
|||
ComponentId(*index)
|
||||
}
|
||||
|
||||
/// Gets an iterator over all components registered with this instance.
|
||||
pub fn iter(&self) -> impl Iterator<Item = &ComponentInfo> + '_ {
|
||||
self.components.iter()
|
||||
}
|
||||
|
@ -602,6 +657,7 @@ impl Tick {
|
|||
/// ticks are periodically scanned to ensure their relative values are below this.
|
||||
pub const MAX: Self = Self::new(MAX_CHANGE_AGE);
|
||||
|
||||
/// Creates a new [`Tick`] wrapping the given value.
|
||||
#[inline]
|
||||
pub const fn new(tick: u32) -> Self {
|
||||
Self { tick }
|
||||
|
@ -659,10 +715,12 @@ impl Tick {
|
|||
}
|
||||
}
|
||||
|
||||
/// Wrapper around [`Tick`]s for a single component
|
||||
/// Interior-mutable access to the [`Tick`]s for a single component or resource.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct TickCells<'a> {
|
||||
/// The tick indicating when the value was added to the world.
|
||||
pub added: &'a UnsafeCell<Tick>,
|
||||
/// The tick indicating the last time the value was modified.
|
||||
pub changed: &'a UnsafeCell<Tick>,
|
||||
}
|
||||
|
||||
|
|
|
@ -717,8 +717,8 @@ impl Entities {
|
|||
}
|
||||
}
|
||||
|
||||
// Flushes all reserved entities to an "invalid" state. Attempting to retrieve them will return None
|
||||
// unless they are later populated with a valid archetype.
|
||||
/// Flushes all reserved entities to an "invalid" state. Attempting to retrieve them will return `None`
|
||||
/// unless they are later populated with a valid archetype.
|
||||
pub fn flush_as_invalid(&mut self) {
|
||||
// SAFETY: as per `flush` safety docs, the archetype id can be set to [`ArchetypeId::INVALID`] if
|
||||
// the [`Entity`] has not been assigned to an [`Archetype`][crate::archetype::Archetype], which is the case here
|
||||
|
|
|
@ -19,11 +19,15 @@ use std::{
|
|||
/// Events must be thread-safe.
|
||||
pub trait Event: Send + Sync + 'static {}
|
||||
|
||||
/// An `EventId` uniquely identifies an event.
|
||||
/// An `EventId` uniquely identifies an event stored in a specific [`World`].
|
||||
///
|
||||
/// An `EventId` can among other things be used to trace the flow of an event from the point it was
|
||||
/// sent to the point it was processed.
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
pub struct EventId<E: Event> {
|
||||
/// Uniquely identifies the event associated with this ID.
|
||||
// This value corresponds to the order in which each event was added to the world.
|
||||
pub id: usize,
|
||||
_marker: PhantomData<E>,
|
||||
}
|
||||
|
@ -178,6 +182,7 @@ impl<E: Event> Default for Events<E> {
|
|||
}
|
||||
|
||||
impl<E: Event> Events<E> {
|
||||
/// Returns the index of the oldest event stored in the event buffer.
|
||||
pub fn oldest_event_count(&self) -> usize {
|
||||
self.events_a
|
||||
.start_event_count
|
||||
|
@ -333,12 +338,17 @@ pub struct EventWriter<'w, E: Event> {
|
|||
}
|
||||
|
||||
impl<'w, E: Event> EventWriter<'w, E> {
|
||||
/// Sends an `event`. [`EventReader`]s can then read the event.
|
||||
/// Sends an `event`, which can later be read by [`EventReader`]s.
|
||||
///
|
||||
/// See [`Events`] for details.
|
||||
pub fn send(&mut self, event: E) {
|
||||
self.events.send(event);
|
||||
}
|
||||
|
||||
/// Sends a list of `events` all at once, which can later be read by [`EventReader`]s.
|
||||
/// This is more efficient than sending each event individually.
|
||||
///
|
||||
/// See [`Events`] for details.
|
||||
pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>) {
|
||||
self.events.extend(events);
|
||||
}
|
||||
|
@ -352,6 +362,8 @@ impl<'w, E: Event> EventWriter<'w, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Stores the state for an [`EventReader`].
|
||||
/// Access to the [`Events<E>`] resource is required to read any incoming events.
|
||||
#[derive(Debug)]
|
||||
pub struct ManualEventReader<E: Event> {
|
||||
last_event_count: usize,
|
||||
|
@ -412,6 +424,7 @@ impl<E: Event> ManualEventReader<E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// An iterator that yields any unread events from an [`EventReader`] or [`ManualEventReader`].
|
||||
pub struct ManualEventIterator<'a, E: Event> {
|
||||
iter: ManualEventIteratorWithId<'a, E>,
|
||||
}
|
||||
|
@ -448,6 +461,7 @@ impl<'a, E: Event> ExactSizeIterator for ManualEventIterator<'a, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// An iterator that yields any unread events (and their IDs) from an [`EventReader`] or [`ManualEventReader`].
|
||||
#[derive(Debug)]
|
||||
pub struct ManualEventIteratorWithId<'a, E: Event> {
|
||||
reader: &'a mut ManualEventReader<E>,
|
||||
|
@ -456,6 +470,7 @@ pub struct ManualEventIteratorWithId<'a, E: Event> {
|
|||
}
|
||||
|
||||
impl<'a, E: Event> ManualEventIteratorWithId<'a, E> {
|
||||
/// Creates a new iterator that yields any `events` that have not yet been seen by `reader`.
|
||||
pub fn new(reader: &'a mut ManualEventReader<E>, events: &'a Events<E>) -> Self {
|
||||
let a_index = (reader.last_event_count).saturating_sub(events.events_a.start_event_count);
|
||||
let b_index = (reader.last_event_count).saturating_sub(events.events_b.start_event_count);
|
||||
|
@ -606,12 +621,13 @@ impl<E: Event> Events<E> {
|
|||
self.events_b.clear();
|
||||
}
|
||||
|
||||
/// Returns the number of events currently stored in the event buffer.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.events_a.len() + self.events_b.len()
|
||||
}
|
||||
|
||||
/// Returns true if there are no events in this collection.
|
||||
/// Returns true if there are no events currently stored in the event buffer.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![warn(clippy::undocumented_unsafe_blocks)]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
|
|
|
@ -302,6 +302,7 @@ impl<T: SparseSetIndex> FilteredAccess<T> {
|
|||
self.filter_sets.append(&mut other.filter_sets.clone());
|
||||
}
|
||||
|
||||
/// Adds all of the accesses from `other` to `self`.
|
||||
pub fn extend_access(&mut self, other: &FilteredAccess<T>) {
|
||||
self.access.extend(&other.access);
|
||||
}
|
||||
|
@ -502,6 +503,7 @@ impl<T: SparseSetIndex> FilteredAccessSet<T> {
|
|||
self.add(filter);
|
||||
}
|
||||
|
||||
/// Adds all of the accesses from the passed set to `self`.
|
||||
pub fn extend(&mut self, filtered_access_set: FilteredAccessSet<T>) {
|
||||
self.combined_access
|
||||
.extend(&filtered_access_set.combined_access);
|
||||
|
@ -509,6 +511,7 @@ impl<T: SparseSetIndex> FilteredAccessSet<T> {
|
|||
.extend(filtered_access_set.filtered_accesses);
|
||||
}
|
||||
|
||||
/// Removes all accesses stored in this set.
|
||||
pub fn clear(&mut self) {
|
||||
self.combined_access.clear();
|
||||
self.filtered_accesses.clear();
|
||||
|
|
|
@ -419,9 +419,12 @@ pub unsafe trait WorldQuery {
|
|||
true
|
||||
}
|
||||
|
||||
/// Adds any component accesses used by this [`WorldQuery`] to `access`.
|
||||
// This does not have a default body of `{}` because 99% of cases need to add accesses
|
||||
// and forgetting to do so would be unsound.
|
||||
fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>);
|
||||
|
||||
/// For the given `archetype`, adds any component accessed used by this [`WorldQuery`] to `access`.
|
||||
// This does not have a default body of `{}` because 99% of cases need to add accesses
|
||||
// and forgetting to do so would be unsound.
|
||||
fn update_archetype_component_access(
|
||||
|
@ -430,7 +433,10 @@ pub unsafe trait WorldQuery {
|
|||
access: &mut Access<ArchetypeComponentId>,
|
||||
);
|
||||
|
||||
/// Creates and initializes a [`State`](WorldQuery::State) for this [`WorldQuery`] type.
|
||||
fn init_state(world: &mut World) -> Self::State;
|
||||
|
||||
/// Returns `true` if this query matches a set of components. Otherwise, returns `false`.
|
||||
fn matches_component_set(
|
||||
state: &Self::State,
|
||||
set_contains_id: &impl Fn(ComponentId) -> bool,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Contains APIs for retrieving component data from the world.
|
||||
|
||||
mod access;
|
||||
mod fetch;
|
||||
mod filter;
|
||||
|
|
|
@ -54,16 +54,19 @@ impl BatchingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
/// Configures the minimum allowed batch size of this instance.
|
||||
pub const fn min_batch_size(mut self, batch_size: usize) -> Self {
|
||||
self.batch_size_limits.start = batch_size;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures the maximum allowed batch size of this instance.
|
||||
pub const fn max_batch_size(mut self, batch_size: usize) -> Self {
|
||||
self.batch_size_limits.end = batch_size;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures the number of batches to assign to each thread for this instance.
|
||||
pub fn batches_per_thread(mut self, batches_per_thread: usize) -> Self {
|
||||
assert!(
|
||||
batches_per_thread > 0,
|
||||
|
|
|
@ -145,7 +145,7 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `world.id()` does not equal the current [`QueryState`] internal id.
|
||||
/// If `world` does not match the one used to call `QueryState::new` for this instance.
|
||||
pub fn update_archetypes(&mut self, world: &World) {
|
||||
self.validate_world(world);
|
||||
let archetypes = world.archetypes();
|
||||
|
@ -158,6 +158,12 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
///
|
||||
/// If `world` does not match the one used to call `QueryState::new` for this instance.
|
||||
///
|
||||
/// Many unsafe query methods require the world to match for soundness. This function is the easiest
|
||||
/// way of ensuring that it matches.
|
||||
#[inline]
|
||||
pub fn validate_world(&self, world: &World) {
|
||||
assert!(
|
||||
|
@ -337,6 +343,17 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the query result for the given [`World`] and [`Entity`].
|
||||
///
|
||||
/// This method is slightly more efficient than [`QueryState::get`] in some situations, since
|
||||
/// it does not update this instance's internal cache. This method will return an error if `entity`
|
||||
/// belongs to an archetype that has not been cached.
|
||||
///
|
||||
/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
|
||||
/// The cache is also updated in [`QueryState::new`], `QueryState::get`, or any method with mutable
|
||||
/// access to `self`.
|
||||
///
|
||||
/// This can only be called for read-only queries, see [`Self::get_mut`] for mutable queries.
|
||||
#[inline]
|
||||
pub fn get_manual<'w>(
|
||||
&self,
|
||||
|
|
|
@ -410,6 +410,11 @@ impl<C: Resource + Reflect + FromWorld> FromType<C> for ReflectResource {
|
|||
impl_reflect_value!((in bevy_ecs) Entity(Hash, PartialEq, Serialize, Deserialize));
|
||||
impl_from_reflect_value!(Entity);
|
||||
|
||||
/// For a specific type of component, this maps any fields with values of type [`Entity`] to a new world.
|
||||
/// Since a given `Entity` ID is only valid for the world it came frome, when performing deserialization
|
||||
/// any stored IDs need to be re-allocated in the destination world.
|
||||
///
|
||||
/// See [`MapEntities`] for more information.
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectMapEntities {
|
||||
map_all_entities: fn(&mut World, &mut EntityMapper),
|
||||
|
|
|
@ -65,24 +65,27 @@ impl<T: Component> DerefMut for RemovedComponentReader<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Wrapper around a map of components to [`Events<RemovedComponentEntity>`].
|
||||
/// So that we can find the events without naming the type directly.
|
||||
/// Stores the [`RemovedComponents`] event buffers for all types of component in a given [`World`].
|
||||
#[derive(Default, Debug)]
|
||||
pub struct RemovedComponentEvents {
|
||||
event_sets: SparseSet<ComponentId, Events<RemovedComponentEntity>>,
|
||||
}
|
||||
|
||||
impl RemovedComponentEvents {
|
||||
/// Creates an empty storage buffer for component removal events.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// For each type of component, swaps the event buffers and clears the oldest event buffer.
|
||||
/// In general, this should be called once per frame/update.
|
||||
pub fn update(&mut self) {
|
||||
for (_component_id, events) in self.event_sets.iter_mut() {
|
||||
events.update();
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the event storage for a given component.
|
||||
pub fn get(
|
||||
&self,
|
||||
component_id: impl Into<ComponentId>,
|
||||
|
@ -90,6 +93,7 @@ impl RemovedComponentEvents {
|
|||
self.event_sets.get(component_id.into())
|
||||
}
|
||||
|
||||
/// Sends a removal event for the specified component.
|
||||
pub fn send(&mut self, component_id: impl Into<ComponentId>, entity: Entity) {
|
||||
self.event_sets
|
||||
.get_or_insert_with(component_id.into(), Default::default)
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::system::{CombinatorSystem, Combine, IntoSystem, ReadOnlySystem, Syste
|
|||
use crate::world::unsafe_world_cell::UnsafeWorldCell;
|
||||
use crate::world::World;
|
||||
|
||||
/// A type-erased run condition stored in a [`Box`].
|
||||
pub type BoxedCondition<In = ()> = Box<dyn ReadOnlySystem<In = In, Out = bool>>;
|
||||
|
||||
/// A system that determines if one or more scheduled systems should run.
|
||||
|
@ -178,6 +179,7 @@ mod sealed {
|
|||
}
|
||||
}
|
||||
|
||||
/// A collection of [run conditions](Condition) that may be useful in any bevy app.
|
||||
pub mod common_conditions {
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ impl IntoSystemConfigs<()> for BoxedSystem<(), ()> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Stores configuration for a single system.
|
||||
pub struct SystemConfig {
|
||||
pub(crate) system: BoxedSystem,
|
||||
pub(crate) graph_info: GraphInfo,
|
||||
|
@ -56,9 +57,13 @@ pub struct SystemConfig {
|
|||
|
||||
/// A collection of [`SystemConfig`].
|
||||
pub enum SystemConfigs {
|
||||
/// Configuration for a single system.
|
||||
SystemConfig(SystemConfig),
|
||||
/// Configuration for a tuple of nested `SystemConfigs` instances.
|
||||
Configs {
|
||||
/// Configuration for each element of the tuple.
|
||||
configs: Vec<SystemConfigs>,
|
||||
/// Run conditions applied to everything in the tuple.
|
||||
collective_conditions: Vec<BoxedCondition>,
|
||||
/// If `true`, adds `before -> after` ordering constraints between the successive elements.
|
||||
chained: bool,
|
||||
|
@ -381,6 +386,7 @@ impl IntoSystemConfigs<()> for SystemConfigs {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct SystemConfigTupleMarker;
|
||||
|
||||
macro_rules! impl_system_collection {
|
||||
|
|
|
@ -62,6 +62,7 @@ pub struct SystemSchedule {
|
|||
}
|
||||
|
||||
impl SystemSchedule {
|
||||
/// Creates an empty [`SystemSchedule`].
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
systems: Vec::new(),
|
||||
|
|
|
@ -256,6 +256,9 @@ impl SystemExecutor for MultiThreadedExecutor {
|
|||
}
|
||||
|
||||
impl MultiThreadedExecutor {
|
||||
/// Creates a new multi-threaded executor for use with a [`Schedule`].
|
||||
///
|
||||
/// [`Schedule`]: crate::schedule::Schedule
|
||||
pub fn new() -> Self {
|
||||
let (sender, receiver) = async_channel::unbounded();
|
||||
Self {
|
||||
|
@ -735,6 +738,7 @@ impl Default for MainThreadExecutor {
|
|||
}
|
||||
|
||||
impl MainThreadExecutor {
|
||||
/// Creates a new executor that can be used to run systems on the main thread.
|
||||
pub fn new() -> Self {
|
||||
MainThreadExecutor(TaskPool::get_thread_executor())
|
||||
}
|
||||
|
|
|
@ -98,6 +98,8 @@ impl SystemExecutor for SimpleExecutor {
|
|||
}
|
||||
|
||||
impl SimpleExecutor {
|
||||
/// Creates a new simple executor for use in a [`Schedule`](crate::schedule::Schedule).
|
||||
/// This calls each system in order and immediately calls [`System::apply_deferred`](crate::system::System::apply_deferred).
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
evaluated_sets: FixedBitSet::new(),
|
||||
|
|
|
@ -116,6 +116,9 @@ impl SystemExecutor for SingleThreadedExecutor {
|
|||
}
|
||||
|
||||
impl SingleThreadedExecutor {
|
||||
/// Creates a new single-threaded executor for use in a [`Schedule`].
|
||||
///
|
||||
/// [`Schedule`]: crate::schedule::Schedule
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
evaluated_sets: FixedBitSet::new(),
|
||||
|
|
|
@ -8,10 +8,14 @@ use fixedbitset::FixedBitSet;
|
|||
|
||||
use crate::schedule::set::*;
|
||||
|
||||
/// Unique identifier for a system or system set.
|
||||
/// Unique identifier for a system or system set stored in a [`ScheduleGraph`].
|
||||
///
|
||||
/// [`ScheduleGraph`]: super::ScheduleGraph
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum NodeId {
|
||||
/// Identifier for a system.
|
||||
System(usize),
|
||||
/// Identifier for a system set.
|
||||
Set(usize),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Contains APIs for ordering systems and executing them on a [`World`](crate::world::World)
|
||||
|
||||
mod condition;
|
||||
mod config;
|
||||
mod executor;
|
||||
|
|
|
@ -399,6 +399,7 @@ pub struct ScheduleGraph {
|
|||
}
|
||||
|
||||
impl ScheduleGraph {
|
||||
/// Creates an empty [`ScheduleGraph`] with default settings.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
systems: Vec::new(),
|
||||
|
@ -1569,6 +1570,8 @@ impl Default for ScheduleBuildSettings {
|
|||
}
|
||||
|
||||
impl ScheduleBuildSettings {
|
||||
/// Default build settings.
|
||||
/// See the field-level documentation for the default value of each field.
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
ambiguity_detection: LogLevel::Ignore,
|
||||
|
|
|
@ -14,7 +14,9 @@ use crate::system::{
|
|||
|
||||
define_boxed_label!(ScheduleLabel);
|
||||
|
||||
/// A shorthand for `Box<dyn SystemSet>`.
|
||||
pub type BoxedSystemSet = Box<dyn SystemSet>;
|
||||
/// A shorthand for `Box<dyn ScheduleLabel>`.
|
||||
pub type BoxedScheduleLabel = Box<dyn ScheduleLabel>;
|
||||
|
||||
/// Types that identify logical groups of systems.
|
||||
|
@ -132,8 +134,10 @@ impl SystemSet for AnonymousSet {
|
|||
|
||||
/// Types that can be converted into a [`SystemSet`].
|
||||
pub trait IntoSystemSet<Marker>: Sized {
|
||||
/// The type of [`SystemSet`] this instance converts into.
|
||||
type Set: SystemSet;
|
||||
|
||||
/// Converts this instance to its associated [`SystemSet`] type.
|
||||
fn into_system_set(self) -> Self::Set;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ pub use bevy_ecs_macros::States;
|
|||
///
|
||||
/// ```
|
||||
pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug + Default {
|
||||
/// The type returned when iterating over all [`variants`](States::variants) of this type.
|
||||
type Iter: Iterator<Item = Self>;
|
||||
|
||||
/// Returns an iterator over all the state variants.
|
||||
|
|
|
@ -539,7 +539,9 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
|
|||
/// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet`
|
||||
/// is proportional to the **value** of those `usize`.
|
||||
pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
|
||||
/// Gets the sparse set index corresponding to this instance.
|
||||
fn sparse_set_index(&self) -> usize;
|
||||
/// Creates a new instance of this type with the specified index.
|
||||
fn get_sparse_set_index(value: usize) -> Self;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,9 @@ pub struct CombinatorSystem<Func, A, B> {
|
|||
}
|
||||
|
||||
impl<Func, A, B> CombinatorSystem<Func, A, B> {
|
||||
/// Creates a new system that combines two inner systems.
|
||||
///
|
||||
/// The returned system will only be usable if `Func` implements [`Combine<A, B>`].
|
||||
pub const fn new(a: A, b: B, name: Cow<'static, str>) -> Self {
|
||||
Self {
|
||||
_marker: PhantomData,
|
||||
|
|
|
@ -43,6 +43,7 @@ use super::{Deferred, Resource, SystemBuffer, SystemMeta};
|
|||
/// }
|
||||
/// ```
|
||||
pub trait Command: Send + 'static {
|
||||
/// Executes this command.
|
||||
fn write(self, world: &mut World);
|
||||
}
|
||||
|
||||
|
@ -603,6 +604,7 @@ impl<'w, 's> Commands<'w, 's> {
|
|||
/// }
|
||||
/// ```
|
||||
pub trait EntityCommand: Send + 'static {
|
||||
/// Executes this command for the given [`Entity`].
|
||||
fn write(self, id: Entity, world: &mut World);
|
||||
/// Returns a [`Command`] which executes this [`EntityCommand`] for the given [`Entity`].
|
||||
fn with_entity(self, id: Entity) -> WithEntity<Self>
|
||||
|
@ -857,11 +859,15 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A [`Command`] that consumes an iterator of [`Bundle`]s to spawn a series of entities.
|
||||
///
|
||||
/// This is more efficient than spawning the entities individually.
|
||||
pub struct SpawnBatch<I>
|
||||
where
|
||||
I: IntoIterator,
|
||||
I::Item: Bundle,
|
||||
{
|
||||
/// The iterator that returns the [`Bundle`]s which will be added to each newly-spawned entity.
|
||||
pub bundles_iter: I,
|
||||
}
|
||||
|
||||
|
@ -875,12 +881,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A [`Command`] that consumes an iterator to add a series of [`Bundle`]s to a set of entities.
|
||||
/// If any entities do not already exist in the world, they will be spawned.
|
||||
///
|
||||
/// This is more efficient than inserting the bundles individually.
|
||||
pub struct InsertOrSpawnBatch<I, B>
|
||||
where
|
||||
I: IntoIterator + Send + Sync + 'static,
|
||||
B: Bundle,
|
||||
I::IntoIter: Iterator<Item = (Entity, B)>,
|
||||
{
|
||||
/// The iterator that returns each [entity ID](Entity) and corresponding [`Bundle`].
|
||||
pub bundles_iter: I,
|
||||
}
|
||||
|
||||
|
@ -902,8 +913,10 @@ where
|
|||
}
|
||||
|
||||
/// A [`Command`] that despawns a specific entity.
|
||||
/// This will emit a warning if the entity does not exist.
|
||||
#[derive(Debug)]
|
||||
pub struct Despawn {
|
||||
/// The entity that will be despawned.
|
||||
pub entity: Entity,
|
||||
}
|
||||
|
||||
|
@ -939,6 +952,7 @@ where
|
|||
/// Any components in the bundle that aren't found on the entity will be ignored.
|
||||
#[derive(Debug)]
|
||||
pub struct Remove<T> {
|
||||
/// The entity from which the components will be removed.
|
||||
pub entity: Entity,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
@ -987,6 +1001,7 @@ impl<R: Resource + FromWorld> InitResource<R> {
|
|||
|
||||
/// A [`Command`] that inserts a [`Resource`] into the world.
|
||||
pub struct InsertResource<R: Resource> {
|
||||
/// The resource that will be added to the world.
|
||||
pub resource: R,
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@ impl SystemBuffer for ParallelCommandQueue {
|
|||
}
|
||||
|
||||
impl<'w, 's> ParallelCommands<'w, 's> {
|
||||
/// Temporarily provides access to the [`Commands`] for the current thread.
|
||||
///
|
||||
/// For an example, see the type-level documentation for [`ParallelCommands`].
|
||||
pub fn command_scope<R>(&self, f: impl FnOnce(Commands) -> R) -> R {
|
||||
let store = &self.state.thread_local_storage;
|
||||
let command_queue_cell = store.get_or_default();
|
||||
|
|
|
@ -29,6 +29,8 @@ where
|
|||
marker: PhantomData<fn() -> Marker>,
|
||||
}
|
||||
|
||||
/// A marker type used to distinguish exclusive function systems from regular function systems.
|
||||
#[doc(hidden)]
|
||||
pub struct IsExclusiveFunctionSystem;
|
||||
|
||||
impl<Marker, F> IntoSystem<F::In, F::Out, (IsExclusiveFunctionSystem, Marker)> for F
|
||||
|
|
|
@ -7,15 +7,26 @@ use crate::{
|
|||
use bevy_utils::all_tuples;
|
||||
use bevy_utils::synccell::SyncCell;
|
||||
|
||||
/// A parameter that can be used in an exclusive system (a system with an `&mut World` parameter).
|
||||
/// Any parameters implementing this trait must come after the `&mut World` parameter.
|
||||
pub trait ExclusiveSystemParam: Sized {
|
||||
/// Used to store data which persists across invocations of a system.
|
||||
type State: Send + Sync + 'static;
|
||||
/// The item type returned when constructing this system param.
|
||||
/// See [`SystemParam::Item`].
|
||||
type Item<'s>: ExclusiveSystemParam<State = Self::State>;
|
||||
|
||||
/// Creates a new instance of this param's [`State`](Self::State).
|
||||
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State;
|
||||
|
||||
/// Creates a parameter to be passed into an [`ExclusiveSystemParamFunction`].
|
||||
///
|
||||
/// [`ExclusiveSystemParamFunction`]: super::ExclusiveSystemParamFunction
|
||||
fn get_param<'s>(state: &'s mut Self::State, system_meta: &SystemMeta) -> Self::Item<'s>;
|
||||
}
|
||||
|
||||
/// Shorthand way of accessing the associated type [`ExclusiveSystemParam::Item`]
|
||||
/// for a given [`ExclusiveSystemParam`].
|
||||
pub type ExclusiveSystemParamItem<'s, P> = <P as ExclusiveSystemParam>::Item<'s>;
|
||||
|
||||
impl<'a, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> ExclusiveSystemParam
|
||||
|
|
|
@ -152,6 +152,13 @@ pub struct SystemState<Param: SystemParam + 'static> {
|
|||
}
|
||||
|
||||
impl<Param: SystemParam> SystemState<Param> {
|
||||
/// Creates a new [`SystemState`] with default state.
|
||||
///
|
||||
/// ## Note
|
||||
/// For users of [`SystemState::get_manual`] or [`get_manual_mut`](SystemState::get_manual_mut):
|
||||
///
|
||||
/// `new` does not cache any of the world's archetypes, so you must call [`SystemState::update_archetypes`]
|
||||
/// manually before calling `get_manual{_mut}`.
|
||||
pub fn new(world: &mut World) -> Self {
|
||||
let mut meta = SystemMeta::new::<Param>();
|
||||
meta.last_run = world.change_tick().relative_to(Tick::MAX);
|
||||
|
@ -164,6 +171,7 @@ impl<Param: SystemParam> SystemState<Param> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the metadata for this instance.
|
||||
#[inline]
|
||||
pub fn meta(&self) -> &SystemMeta {
|
||||
&self.meta
|
||||
|
@ -198,6 +206,8 @@ impl<Param: SystemParam> SystemState<Param> {
|
|||
Param::apply(&mut self.param_state, &self.meta, world);
|
||||
}
|
||||
|
||||
/// Returns `true` if `world` is the same one that was used to call [`SystemState::new`].
|
||||
/// Otherwise, this returns false.
|
||||
#[inline]
|
||||
pub fn matches_world(&self, world: &World) -> bool {
|
||||
self.world_id == world.id()
|
||||
|
@ -350,6 +360,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A marker type used to distinguish regular function systems from exclusive function systems.
|
||||
#[doc(hidden)]
|
||||
pub struct IsFunctionSystem;
|
||||
|
||||
impl<Marker, F> IntoSystem<F::In, F::Out, (IsFunctionSystem, Marker)> for F
|
||||
|
|
|
@ -208,7 +208,9 @@ where
|
|||
// because Rust thinks a type could impl multiple different `FnMut` combinations
|
||||
// even though none can currently
|
||||
pub trait IntoSystem<In, Out, Marker>: Sized {
|
||||
/// The type of [`System`] that this instance converts into.
|
||||
type System: System<In = In, Out = Out>;
|
||||
|
||||
/// Turns this value into its corresponding [`System`].
|
||||
fn into_system(this: Self) -> Self::System;
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ pub trait System: Send + Sync + 'static {
|
|||
unsafe { self.run_unsafe(input, world) }
|
||||
}
|
||||
/// Applies any [`Deferred`](crate::system::Deferred) system parameters (or other system buffers) of this system to the world.
|
||||
///
|
||||
/// This is where [`Commands`](crate::system::Commands) get applied.
|
||||
fn apply_deferred(&mut self, world: &mut World);
|
||||
/// Initialize the system.
|
||||
fn initialize(&mut self, _world: &mut World);
|
||||
|
@ -71,6 +73,10 @@ pub trait System: Send + Sync + 'static {
|
|||
/// `world` may only be used to access metadata. This can be done in safe code
|
||||
/// via functions such as [`UnsafeWorldCell::archetypes`].
|
||||
fn update_archetype_component_access(&mut self, world: UnsafeWorldCell);
|
||||
/// Checks any [`Tick`]s stored on this system and wraps their value if they get too old.
|
||||
///
|
||||
/// This method must be called periodically to ensure that change detection behaves correctly.
|
||||
/// When using bevy's default configuration, this will be called for you as needed.
|
||||
fn check_change_tick(&mut self, change_tick: Tick);
|
||||
/// Returns the system's default [system sets](crate::schedule::SystemSet).
|
||||
fn default_system_sets(&self) -> Vec<Box<dyn crate::schedule::SystemSet>> {
|
||||
|
|
|
@ -125,6 +125,10 @@ pub unsafe trait SystemParam: Sized {
|
|||
#[allow(unused_variables)]
|
||||
fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {}
|
||||
|
||||
/// Creates a parameter to be passed into a [`SystemParamFunction`].
|
||||
///
|
||||
/// [`SystemParamFunction`]: super::SystemParamFunction
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - The passed [`UnsafeWorldCell`] must have access to any world data
|
||||
|
@ -1307,6 +1311,7 @@ pub struct SystemName<'s> {
|
|||
}
|
||||
|
||||
impl<'s> SystemName<'s> {
|
||||
/// Gets the name of the system.
|
||||
pub fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
@ -1413,12 +1418,23 @@ macro_rules! impl_system_param_tuple {
|
|||
|
||||
all_tuples!(impl_system_param_tuple, 0, 16, P);
|
||||
|
||||
/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
|
||||
/// This can make it more convenient to refer to these types in contexts where
|
||||
/// explicit lifetime annotations are required.
|
||||
///
|
||||
/// [`SystemParam`]: super::SystemParam
|
||||
pub mod lifetimeless {
|
||||
/// A [`Query`](super::Query) with `'static` lifetimes.
|
||||
pub type SQuery<Q, F = ()> = super::Query<'static, 'static, Q, F>;
|
||||
/// A shorthand for writing `&'static T`.
|
||||
pub type Read<T> = &'static T;
|
||||
/// A shorthand for writing `&'static mut T`.
|
||||
pub type Write<T> = &'static mut T;
|
||||
/// A [`Res`](super::Res) with `'static` lifetimes.
|
||||
pub type SRes<T> = super::Res<'static, T>;
|
||||
/// A [`ResMut`](super::ResMut) with `'static` lifetimes.
|
||||
pub type SResMut<T> = super::ResMut<'static, T>;
|
||||
/// [`Commands`](crate::system::Commands) with `'static` lifetimes.
|
||||
pub type SCommands = crate::system::Commands<'static, 'static>;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,44 +49,72 @@ impl<'w> EntityRef<'w> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Returns the [ID](Entity) of the current entity.
|
||||
#[inline]
|
||||
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
|
||||
pub fn id(&self) -> Entity {
|
||||
self.entity
|
||||
}
|
||||
|
||||
/// Gets metadata indicating the location where the current entity is stored.
|
||||
#[inline]
|
||||
pub fn location(&self) -> EntityLocation {
|
||||
self.location
|
||||
}
|
||||
|
||||
/// Returns the archetype that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn archetype(&self) -> &Archetype {
|
||||
&self.world.archetypes[self.location.archetype_id]
|
||||
}
|
||||
|
||||
/// Gets read-only access to the world that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn world(&self) -> &'w World {
|
||||
self.world
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component of type `T`.
|
||||
/// Otherwise, this returns `false`.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// If you do not know the concrete type of a component, consider using
|
||||
/// [`Self::contains_id`] or [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains<T: Component>(&self) -> bool {
|
||||
self.contains_type_id(TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component identified by `component_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
|
||||
/// [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains_id(&self, component_id: ComponentId) -> bool {
|
||||
self.as_unsafe_world_cell_readonly()
|
||||
.contains_id(component_id)
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
|
||||
#[inline]
|
||||
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
|
||||
self.as_unsafe_world_cell_readonly()
|
||||
.contains_type_id(type_id)
|
||||
}
|
||||
|
||||
/// Gets access to the component of type `T` for the current entity.
|
||||
/// Returns `None` if the entity does not have a component of type `T`.
|
||||
#[inline]
|
||||
pub fn get<T: Component>(&self) -> Option<&'w T> {
|
||||
// SAFETY: &self implies shared access for duration of returned value
|
||||
|
@ -186,45 +214,74 @@ impl<'w> EntityMut<'w> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the [ID](Entity) of the current entity.
|
||||
#[inline]
|
||||
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
|
||||
pub fn id(&self) -> Entity {
|
||||
self.entity
|
||||
}
|
||||
|
||||
/// Gets metadata indicating the location where the current entity is stored.
|
||||
#[inline]
|
||||
pub fn location(&self) -> EntityLocation {
|
||||
self.location
|
||||
}
|
||||
|
||||
/// Returns the archetype that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn archetype(&self) -> &Archetype {
|
||||
&self.world.archetypes[self.location.archetype_id]
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component of type `T`.
|
||||
/// Otherwise, this returns `false`.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// If you do not know the concrete type of a component, consider using
|
||||
/// [`Self::contains_id`] or [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains<T: Component>(&self) -> bool {
|
||||
self.contains_type_id(TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component identified by `component_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
|
||||
/// [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains_id(&self, component_id: ComponentId) -> bool {
|
||||
self.as_unsafe_world_cell_readonly()
|
||||
.contains_id(component_id)
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
|
||||
#[inline]
|
||||
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
|
||||
self.as_unsafe_world_cell_readonly()
|
||||
.contains_type_id(type_id)
|
||||
}
|
||||
|
||||
/// Gets access to the component of type `T` for the current entity.
|
||||
/// Returns `None` if the entity does not have a component of type `T`.
|
||||
#[inline]
|
||||
pub fn get<T: Component>(&self) -> Option<&'_ T> {
|
||||
// SAFETY: &self implies shared access for duration of returned value
|
||||
unsafe { self.as_unsafe_world_cell_readonly().get::<T>() }
|
||||
}
|
||||
|
||||
/// Gets mutable access to the component of type `T` for the current entity.
|
||||
/// Returns `None` if the entity does not have a component of type `T`.
|
||||
#[inline]
|
||||
pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>> {
|
||||
// SAFETY: &mut self implies exclusive access for duration of returned value
|
||||
|
@ -580,6 +637,7 @@ impl<'w> EntityMut<'w> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Despawns the current entity.
|
||||
pub fn despawn(self) {
|
||||
debug!("Despawning entity {:?}", self.entity);
|
||||
let world = self.world;
|
||||
|
@ -645,6 +703,7 @@ impl<'w> EntityMut<'w> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets read-only access to the world that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn world(&self) -> &World {
|
||||
self.world
|
||||
|
@ -663,7 +722,7 @@ impl<'w> EntityMut<'w> {
|
|||
self.world
|
||||
}
|
||||
|
||||
/// Return this `EntityMut`'s [`World`], consuming itself.
|
||||
/// Returns this `EntityMut`'s [`World`], consuming itself.
|
||||
#[inline]
|
||||
pub fn into_world_mut(self) -> &'w mut World {
|
||||
self.world
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Contains error types returned by bevy's schedule.
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::schedule::BoxedScheduleLabel;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Defines the [`World`] and APIs for accessing it directly.
|
||||
|
||||
mod entity_ref;
|
||||
pub mod error;
|
||||
mod spawn_batch;
|
||||
|
@ -941,6 +943,13 @@ impl World {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Return's `true` if a resource of type `R` exists and was added since the world's
|
||||
/// [`last_change_tick`](World::last_change_tick()). Otherwise, this return's `false`.
|
||||
///
|
||||
/// This means that:
|
||||
/// - When called from an exclusive system, this will check for additions since the system last ran.
|
||||
/// - When called elsewhere, this will check for additions since the last time that [`World::clear_trackers`]
|
||||
/// was called.
|
||||
pub fn is_resource_added<R: Resource>(&self) -> bool {
|
||||
self.components
|
||||
.get_resource_id(TypeId::of::<R>())
|
||||
|
@ -949,6 +958,13 @@ impl World {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Return's `true` if a resource of type `R` exists and was modified since the world's
|
||||
/// [`last_change_tick`](World::last_change_tick()). Otherwise, this return's `false`.
|
||||
///
|
||||
/// This means that:
|
||||
/// - When called from an exclusive system, this will check for changes since the system last ran.
|
||||
/// - When called elsewhere, this will check for changes since the last time that [`World::clear_trackers`]
|
||||
/// was called.
|
||||
pub fn is_resource_changed<R: Resource>(&self) -> bool {
|
||||
self.components
|
||||
.get_resource_id(TypeId::of::<R>())
|
||||
|
|
|
@ -5,6 +5,10 @@ use crate::{
|
|||
};
|
||||
use std::iter::FusedIterator;
|
||||
|
||||
/// An iterator that spawns a series of entities and returns the [ID](Entity) of
|
||||
/// each spawned entity.
|
||||
///
|
||||
/// If this iterator is not fully exhausted, any remaining entities will be spawned when this type is dropped.
|
||||
pub struct SpawnBatchIter<'w, I>
|
||||
where
|
||||
I: Iterator,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Contains types that allow disjoint mutable access to a [`World`].
|
||||
|
||||
#![warn(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use super::{Mut, World, WorldId};
|
||||
|
@ -577,37 +579,63 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the [ID](Entity) of the current entity.
|
||||
#[inline]
|
||||
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
|
||||
pub fn id(self) -> Entity {
|
||||
self.entity
|
||||
}
|
||||
|
||||
/// Gets metadata indicating the location where the current entity is stored.
|
||||
#[inline]
|
||||
pub fn location(self) -> EntityLocation {
|
||||
self.location
|
||||
}
|
||||
|
||||
/// Returns the archetype that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn archetype(self) -> &'w Archetype {
|
||||
&self.world.archetypes()[self.location.archetype_id]
|
||||
}
|
||||
|
||||
/// Gets the world that the current entity belongs to.
|
||||
#[inline]
|
||||
pub fn world(self) -> UnsafeWorldCell<'w> {
|
||||
self.world
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component of type `T`.
|
||||
/// Otherwise, this returns `false`.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// If you do not know the concrete type of a component, consider using
|
||||
/// [`Self::contains_id`] or [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains<T: Component>(self) -> bool {
|
||||
self.contains_type_id(TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component identified by `component_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
|
||||
/// [`Self::contains_type_id`].
|
||||
#[inline]
|
||||
pub fn contains_id(self, component_id: ComponentId) -> bool {
|
||||
self.archetype().contains(component_id)
|
||||
}
|
||||
|
||||
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
|
||||
/// Otherwise, this returns false.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
|
||||
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
|
||||
#[inline]
|
||||
pub fn contains_type_id(self, type_id: TypeId) -> bool {
|
||||
let id = match self.world.components().get_id(type_id) {
|
||||
|
|
|
@ -91,6 +91,8 @@ impl<'w> Drop for WorldCell<'w> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A read-only borrow of some data stored in a [`World`]. This type is returned by [`WorldCell`],
|
||||
/// which uses run-time checks to ensure that the borrow does not violate Rust's aliasing rules.
|
||||
pub struct WorldBorrow<'w, T> {
|
||||
value: &'w T,
|
||||
archetype_component_id: ArchetypeComponentId,
|
||||
|
@ -133,6 +135,8 @@ impl<'w, T> Drop for WorldBorrow<'w, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A mutable borrow of some data stored in a [`World`]. This type is returned by [`WorldCell`],
|
||||
/// which uses run-time checks to ensure that the borrow does not violate Rust's aliasing rules.
|
||||
pub struct WorldBorrowMut<'w, T> {
|
||||
value: Mut<'w, T>,
|
||||
archetype_component_id: ArchetypeComponentId,
|
||||
|
|
Loading…
Reference in a new issue