Path: blob/main/crates/bevy_ecs/src/change_detection/params.rs
9356 views
use crate::{1change_detection::{traits::*, ComponentTickCells, MaybeLocation, Tick},2ptr::PtrMut,3resource::Resource,4};5use bevy_ptr::{Ptr, ThinSlicePtr, UnsafeCellDeref};6use core::{7cell::UnsafeCell,8ops::{Deref, DerefMut},9panic::Location,10};1112/// Used by immutable query parameters (such as [`Ref`] and [`Res`])13/// to store immutable access to the [`Tick`]s of a single component or resource.14#[derive(Clone)]15pub(crate) struct ComponentTicksRef<'w> {16pub(crate) added: &'w Tick,17pub(crate) changed: &'w Tick,18pub(crate) changed_by: MaybeLocation<&'w &'static Location<'static>>,19pub(crate) last_run: Tick,20pub(crate) this_run: Tick,21}2223impl<'w> ComponentTicksRef<'w> {24/// # Safety25/// This should never alias the underlying ticks with a mutable one such as `ComponentTicksMut`.26#[inline]27pub(crate) unsafe fn from_tick_cells(28cells: ComponentTickCells<'w>,29last_run: Tick,30this_run: Tick,31) -> Self {32Self {33// SAFETY: Caller ensures there is no mutable access to the cell.34added: unsafe { cells.added.deref() },35// SAFETY: Caller ensures there is no mutable access to the cell.36changed: unsafe { cells.changed.deref() },37// SAFETY: Caller ensures there is no mutable access to the cell.38changed_by: unsafe { cells.changed_by.map(|changed_by| changed_by.deref()) },39last_run,40this_run,41}42}43}4445/// Data type storing contiguously lying ticks.46///47/// Retrievable via [`ContiguousRef::split`] and probably only useful if you want to use the following48/// methods:49/// - [`ContiguousComponentTicksRef::is_changed_iter`],50/// - [`ContiguousComponentTicksRef::is_added_iter`]51#[derive(Clone)]52pub struct ContiguousComponentTicksRef<'w> {53pub(crate) added: &'w [Tick],54pub(crate) changed: &'w [Tick],55pub(crate) changed_by: MaybeLocation<&'w [&'static Location<'static>]>,56pub(crate) last_run: Tick,57pub(crate) this_run: Tick,58}5960impl<'w> ContiguousComponentTicksRef<'w> {61/// # Safety62/// - The caller must have permission for all given ticks to be read.63/// - `len` must be the length of `added`, `changed` and `changed_by` (unless none) slices.64pub(crate) unsafe fn from_slice_ptrs(65added: ThinSlicePtr<'w, UnsafeCell<Tick>>,66changed: ThinSlicePtr<'w, UnsafeCell<Tick>>,67changed_by: MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,68len: usize,69this_run: Tick,70last_run: Tick,71) -> Self {72Self {73// SAFETY:74// - The caller ensures that `len` is the length of the slice.75// - The caller ensures we have permission to read the data.76added: unsafe { added.cast().as_slice_unchecked(len) },77// SAFETY: see above.78changed: unsafe { changed.cast().as_slice_unchecked(len) },79// SAFETY: see above.80changed_by: changed_by.map(|v| unsafe { v.cast().as_slice_unchecked(len) }),81last_run,82this_run,83}84}8586/// Creates a new `ContiguousComponentTicksRef` using provided values or returns [`None`] if lengths of87/// `added`, `changed` and `changed_by` do not match88///89/// This is an advanced feature, `ContiguousComponentTicksRef`s are designed to be _created_ by90/// engine-internal code and _consumed_ by end-user code.91///92/// - `added` - [`Tick`]s that store the tick when the wrapped value was created.93/// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.94/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used95/// as a reference to determine whether the wrapped value is newly added or changed.96/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".97/// - `caller` - [`Location`]s that store the location when the wrapper value was changed.98pub fn new(99added: &'w [Tick],100changed: &'w [Tick],101last_run: Tick,102this_run: Tick,103caller: MaybeLocation<&'w [&'static Location<'static>]>,104) -> Option<Self> {105let eq = added.len() == changed.len()106&& caller107.map(|v| v.len() == added.len())108.into_option()109.unwrap_or(true);110eq.then_some(Self {111added,112changed,113changed_by: caller,114last_run,115this_run,116})117}118119/// Returns added ticks' slice.120pub fn added(&self) -> &'w [Tick] {121self.added122}123124/// Returns changed ticks' slice.125pub fn changed(&self) -> &'w [Tick] {126self.changed127}128129/// Returns changed by locations' slice.130pub fn changed_by(&self) -> MaybeLocation<&[&'static Location<'static>]> {131self.changed_by.as_deref()132}133134/// Returns the tick the system last ran.135pub fn last_run(&self) -> Tick {136self.last_run137}138139/// Returns the tick of the current system's run.140pub fn this_run(&self) -> Tick {141self.this_run142}143144/// Returns an iterator where the i-th item corresponds to whether the i-th component was145/// marked as changed. If the value equals [`prim@true`], then the component was changed.146///147/// # Example148/// ```149/// # use bevy_ecs::prelude::*;150/// #151/// # #[derive(Component)]152/// # struct A(pub i32);153///154/// fn some_system(mut query: Query<Ref<A>>) {155/// for a in query.contiguous_iter().unwrap() {156/// let (a_values, a_ticks) = ContiguousRef::split(a);157/// for (value, is_changed) in a_values.iter().zip(a_ticks.is_changed_iter()) {158/// if is_changed {159/// // do something160/// }161/// }162/// }163/// }164/// ```165pub fn is_changed_iter(&self) -> impl Iterator<Item = bool> {166self.changed167.iter()168.map(|v| v.is_newer_than(self.last_run, self.this_run))169}170171/// Returns an iterator where the i-th item corresponds to whether the i-th component was172/// marked as added. If the value equals [`prim@true`], then the component was added.173///174/// # Example175/// ```176/// # use bevy_ecs::prelude::*;177/// #178/// # #[derive(Component)]179/// # struct A(pub i32);180///181/// fn some_system(mut query: Query<Ref<A>>) {182/// for a in query.contiguous_iter().unwrap() {183/// let (a_values, a_ticks) = ContiguousRef::split(a);184/// for (value, is_added) in a_values.iter().zip(a_ticks.is_added_iter()) {185/// if is_added {186/// // do something187/// }188/// }189/// }190/// }191/// ```192pub fn is_added_iter(&self) -> impl Iterator<Item = bool> {193self.added194.iter()195.map(|v| v.is_newer_than(self.last_run, self.this_run))196}197}198199/// Used by mutable query parameters (such as [`Mut`] and [`ResMut`])200/// to store mutable access to the [`Tick`]s of a single component or resource.201pub(crate) struct ComponentTicksMut<'w> {202pub(crate) added: &'w mut Tick,203pub(crate) changed: &'w mut Tick,204pub(crate) changed_by: MaybeLocation<&'w mut &'static Location<'static>>,205pub(crate) last_run: Tick,206pub(crate) this_run: Tick,207}208209impl<'w> ComponentTicksMut<'w> {210/// # Safety211/// This should never alias the underlying ticks. All access must be unique.212#[inline]213pub(crate) unsafe fn from_tick_cells(214cells: ComponentTickCells<'w>,215last_run: Tick,216this_run: Tick,217) -> Self {218Self {219// SAFETY: Caller ensures there is no alias to the cell.220added: unsafe { cells.added.deref_mut() },221// SAFETY: Caller ensures there is no alias to the cell.222changed: unsafe { cells.changed.deref_mut() },223// SAFETY: Caller ensures there is no alias to the cell.224changed_by: unsafe { cells.changed_by.map(|changed_by| changed_by.deref_mut()) },225last_run,226this_run,227}228}229}230231impl<'w> From<ComponentTicksMut<'w>> for ComponentTicksRef<'w> {232fn from(ticks: ComponentTicksMut<'w>) -> Self {233ComponentTicksRef {234added: ticks.added,235changed: ticks.changed,236changed_by: ticks.changed_by.map(|changed_by| &*changed_by),237last_run: ticks.last_run,238this_run: ticks.this_run,239}240}241}242243/// Data type storing contiguously lying ticks, which may be accessed to mutate.244///245/// Retrievable via [`ContiguousMut::split`] and probably only useful if you want to use the following246/// methods:247/// - [`ContiguousComponentTicksMut::is_changed_iter`],248/// - [`ContiguousComponentTicksMut::is_added_iter`]249pub struct ContiguousComponentTicksMut<'w> {250pub(crate) added: &'w mut [Tick],251pub(crate) changed: &'w mut [Tick],252pub(crate) changed_by: MaybeLocation<&'w mut [&'static Location<'static>]>,253pub(crate) last_run: Tick,254pub(crate) this_run: Tick,255}256257impl<'w> ContiguousComponentTicksMut<'w> {258/// # Safety259/// - The caller must have permission to use all given ticks to be mutated.260/// - `len` must be the length of `added`, `changed` and `changed_by` (unless none) slices.261pub(crate) unsafe fn from_slice_ptrs(262added: ThinSlicePtr<'w, UnsafeCell<Tick>>,263changed: ThinSlicePtr<'w, UnsafeCell<Tick>>,264changed_by: MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,265len: usize,266this_run: Tick,267last_run: Tick,268) -> Self {269Self {270// SAFETY:271// - The caller ensures that `len` is the length of the slice.272// - The caller ensures we have permission to mutate the data.273added: unsafe { added.as_mut_slice_unchecked(len) },274// SAFETY: see above.275changed: unsafe { changed.as_mut_slice_unchecked(len) },276// SAFETY: see above.277changed_by: changed_by.map(|v| unsafe { v.as_mut_slice_unchecked(len) }),278last_run,279this_run,280}281}282283/// Creates a new `ContiguousComponentTicksMut` using provided values or returns [`None`] if lengths of284/// `added`, `changed` and `changed_by` do not match285///286/// This is an advanced feature, `ContiguousComponentTicksMut`s are designed to be _created_ by287/// engine-internal code and _consumed_ by end-user code.288///289/// - `added` - [`Tick`]s that store the tick when the wrapped value was created.290/// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.291/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used292/// as a reference to determine whether the wrapped value is newly added or changed.293/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".294/// - `caller` - [`Location`]s that store the location when the wrapper value was changed.295pub fn new(296added: &'w mut [Tick],297changed: &'w mut [Tick],298last_run: Tick,299this_run: Tick,300caller: MaybeLocation<&'w mut [&'static Location<'static>]>,301) -> Option<Self> {302let eq = added.len() == changed.len()303&& caller304.as_ref()305.map(|v| v.len() == added.len())306.into_option()307.unwrap_or(true);308eq.then_some(Self {309added,310changed,311changed_by: caller,312last_run,313this_run,314})315}316317/// Returns added ticks' slice.318pub fn added(&self) -> &[Tick] {319self.added320}321322/// Returns changed ticks' slice.323pub fn changed(&self) -> &[Tick] {324self.changed325}326327/// Returns changed by locations' slice.328pub fn changed_by(&self) -> MaybeLocation<&[&'static Location<'static>]> {329self.changed_by.as_deref()330}331332/// Returns mutable added ticks' slice.333pub fn added_mut(&mut self) -> &mut [Tick] {334self.added335}336337/// Returns mutable changed ticks' slice.338pub fn changed_mut(&mut self) -> &mut [Tick] {339self.changed340}341342/// Returns mutable changed by locations' slice.343pub fn changed_by_mut(&mut self) -> MaybeLocation<&mut [&'static Location<'static>]> {344self.changed_by.as_deref_mut()345}346347/// Returns the tick the system last ran.348pub fn last_run(&self) -> Tick {349self.last_run350}351352/// Returns the tick of the current system's run.353pub fn this_run(&self) -> Tick {354self.this_run355}356357/// Returns an iterator where the i-th item corresponds to whether the i-th component was358/// marked as changed. If the value equals [`prim@true`], then the component was changed.359///360/// # Example361/// ```362/// # use bevy_ecs::prelude::*;363/// #364/// # #[derive(Component)]365/// # struct A(pub i32);366///367/// fn some_system(mut query: Query<&mut A>) {368/// for a in query.contiguous_iter_mut().unwrap() {369/// let (a_values, a_ticks) = ContiguousMut::split(a);370/// for (value, is_changed) in a_values.iter_mut().zip(a_ticks.is_changed_iter()) {371/// if is_changed {372/// value.0 *= 10;373/// }374/// }375/// }376/// }377/// ```378pub fn is_changed_iter(&self) -> impl Iterator<Item = bool> {379self.changed380.iter()381.map(|v| v.is_newer_than(self.last_run, self.this_run))382}383384/// Returns an iterator where the i-th item corresponds to whether the i-th component was385/// marked as added. If the value equals [`prim@true`], then the component was added.386///387/// # Example388/// ```389/// # use bevy_ecs::prelude::*;390/// #391/// # #[derive(Component)]392/// # struct A(pub i32);393///394/// fn some_system(mut query: Query<&mut A>) {395/// for a in query.contiguous_iter_mut().unwrap() {396/// let (a_values, a_ticks) = ContiguousMut::split(a);397/// for (value, is_added) in a_values.iter_mut().zip(a_ticks.is_added_iter()) {398/// if is_added {399/// value.0 = 10;400/// }401/// }402/// }403/// }404/// ```405pub fn is_added_iter(&self) -> impl Iterator<Item = bool> {406self.added407.iter()408.map(|v| v.is_newer_than(self.last_run, self.this_run))409}410411/// Marks every tick as changed.412pub fn mark_all_as_changed(&mut self) {413let this_run = self.this_run;414415self.changed_by.as_mut().map(|v| {416for v in v.iter_mut() {417*v = Location::caller();418}419});420421for t in self.changed.iter_mut() {422*t = this_run;423}424}425426/// Returns a `ContiguousComponentTicksMut` with a smaller lifetime.427pub fn reborrow(&mut self) -> ContiguousComponentTicksMut<'_> {428ContiguousComponentTicksMut {429added: self.added,430changed: self.changed,431changed_by: self.changed_by.as_deref_mut(),432last_run: self.last_run,433this_run: self.this_run,434}435}436}437438impl<'w> From<ContiguousComponentTicksMut<'w>> for ContiguousComponentTicksRef<'w> {439fn from(value: ContiguousComponentTicksMut<'w>) -> Self {440Self {441added: value.added,442changed: value.changed,443changed_by: value.changed_by.map(|v| &*v),444last_run: value.last_run,445this_run: value.this_run,446}447}448}449450/// Shared borrow of a [`Resource`].451///452/// See the [`Resource`] documentation for usage.453///454/// If you need a unique mutable borrow, use [`ResMut`] instead.455///456/// This [`SystemParam`](crate::system::SystemParam) fails validation if resource doesn't exist.457/// This will cause a panic, but can be configured to do nothing or warn once.458///459/// Use [`Option<Res<T>>`] instead if the resource might not always exist.460pub struct Res<'w, T: ?Sized + Resource> {461pub(crate) value: &'w T,462pub(crate) ticks: ComponentTicksRef<'w>,463}464465impl<'w, T: Resource> Res<'w, T> {466/// Copies a reference to a resource.467///468/// Note that unless you actually need an instance of `Res<T>`, you should469/// prefer to just convert it to `&T` which can be freely copied.470#[expect(471clippy::should_implement_trait,472reason = "As this struct derefs to the inner resource, a `Clone` trait implementation would interfere with the common case of cloning the inner content. (A similar case of this happening can be found with `std::cell::Ref::clone()`.)"473)]474pub fn clone(this: &Self) -> Self {475Self {476value: this.value,477ticks: this.ticks.clone(),478}479}480481/// Due to lifetime limitations of the `Deref` trait, this method can be used to obtain a482/// reference of the [`Resource`] with a lifetime bound to `'w` instead of the lifetime of the483/// struct itself.484pub fn into_inner(self) -> &'w T {485self.value486}487}488489impl<'w, T: Resource> From<ResMut<'w, T>> for Res<'w, T> {490fn from(res: ResMut<'w, T>) -> Self {491Self {492value: res.value,493ticks: res.ticks.into(),494}495}496}497498impl<'w, T: Resource> From<Res<'w, T>> for Ref<'w, T> {499/// Convert a `Res` into a `Ref`. This allows keeping the change-detection feature of `Ref`500/// while losing the specificity of `Res` for resources.501fn from(res: Res<'w, T>) -> Self {502Self {503value: res.value,504ticks: res.ticks,505}506}507}508509impl<'w, 'a, T: Resource> IntoIterator for &'a Res<'w, T>510where511&'a T: IntoIterator,512{513type Item = <&'a T as IntoIterator>::Item;514type IntoIter = <&'a T as IntoIterator>::IntoIter;515516fn into_iter(self) -> Self::IntoIter {517self.value.into_iter()518}519}520change_detection_impl!(Res<'w, T>, T, Resource);521impl_debug!(Res<'w, T>, Resource);522523/// Unique mutable borrow of a [`Resource`].524///525/// See the [`Resource`] documentation for usage.526///527/// If you need a shared borrow, use [`Res`] instead.528///529/// This [`SystemParam`](crate::system::SystemParam) fails validation if resource doesn't exist.530/// This will cause a panic, but can be configured to do nothing or warn once.531///532/// Use [`Option<ResMut<T>>`] instead if the resource might not always exist.533pub struct ResMut<'w, T: ?Sized + Resource> {534pub(crate) value: &'w mut T,535pub(crate) ticks: ComponentTicksMut<'w>,536}537538impl<'w, 'a, T: Resource> IntoIterator for &'a ResMut<'w, T>539where540&'a T: IntoIterator,541{542type Item = <&'a T as IntoIterator>::Item;543type IntoIter = <&'a T as IntoIterator>::IntoIter;544545fn into_iter(self) -> Self::IntoIter {546self.value.into_iter()547}548}549550impl<'w, 'a, T: Resource> IntoIterator for &'a mut ResMut<'w, T>551where552&'a mut T: IntoIterator,553{554type Item = <&'a mut T as IntoIterator>::Item;555type IntoIter = <&'a mut T as IntoIterator>::IntoIter;556557fn into_iter(self) -> Self::IntoIter {558self.set_changed();559self.value.into_iter()560}561}562563change_detection_impl!(ResMut<'w, T>, T, Resource);564change_detection_mut_impl!(ResMut<'w, T>, T, Resource);565impl_methods!(ResMut<'w, T>, T, Resource);566impl_debug!(ResMut<'w, T>, Resource);567568impl<'w, T: Resource> From<ResMut<'w, T>> for Mut<'w, T> {569/// Convert this `ResMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`570/// while losing the specificity of `ResMut` for resources.571fn from(other: ResMut<'w, T>) -> Mut<'w, T> {572Mut {573value: other.value,574ticks: other.ticks,575}576}577}578579/// Shared borrow of a non-[`Send`] resource.580///581/// Only [`Send`] resources may be accessed with the [`Res`] [`SystemParam`](crate::system::SystemParam). In case that the582/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct583/// the scheduler to instead run the system on the main thread so that it doesn't send the resource584/// over to another thread.585///586/// This [`SystemParam`](crate::system::SystemParam) fails validation if the non-send resource doesn't exist.587/// This will cause a panic, but can be configured to do nothing or warn once.588///589/// Use [`Option<NonSend<T>>`] instead if the resource might not always exist.590pub struct NonSend<'w, T: ?Sized + 'static> {591pub(crate) value: &'w T,592pub(crate) ticks: ComponentTicksRef<'w>,593}594595change_detection_impl!(NonSend<'w, T>, T,);596impl_debug!(NonSend<'w, T>,);597598impl<'w, T> From<NonSendMut<'w, T>> for NonSend<'w, T> {599fn from(other: NonSendMut<'w, T>) -> Self {600Self {601value: other.value,602ticks: other.ticks.into(),603}604}605}606607/// Unique borrow of a non-[`Send`] resource.608///609/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the610/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct611/// the scheduler to instead run the system on the main thread so that it doesn't send the resource612/// over to another thread.613///614/// This [`SystemParam`](crate::system::SystemParam) fails validation if non-send resource doesn't exist.615/// This will cause a panic, but can be configured to do nothing or warn once.616///617/// Use [`Option<NonSendMut<T>>`] instead if the resource might not always exist.618pub struct NonSendMut<'w, T: ?Sized + 'static> {619pub(crate) value: &'w mut T,620pub(crate) ticks: ComponentTicksMut<'w>,621}622623change_detection_impl!(NonSendMut<'w, T>, T,);624change_detection_mut_impl!(NonSendMut<'w, T>, T,);625impl_methods!(NonSendMut<'w, T>, T,);626impl_debug!(NonSendMut<'w, T>,);627628impl<'w, T: 'static> From<NonSendMut<'w, T>> for Mut<'w, T> {629/// Convert this `NonSendMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`630/// while losing the specificity of `NonSendMut`.631fn from(other: NonSendMut<'w, T>) -> Mut<'w, T> {632Mut {633value: other.value,634ticks: other.ticks,635}636}637}638639/// Shared borrow of an entity's component with access to change detection.640/// Similar to [`Mut`] but is immutable and so doesn't require unique access.641///642/// # Examples643///644/// These two systems produce the same output.645///646/// ```647/// # use bevy_ecs::change_detection::DetectChanges;648/// # use bevy_ecs::query::{Changed, With};649/// # use bevy_ecs::system::Query;650/// # use bevy_ecs::world::Ref;651/// # use bevy_ecs_macros::Component;652/// # #[derive(Component)]653/// # struct MyComponent;654///655/// fn how_many_changed_1(query: Query<(), Changed<MyComponent>>) {656/// println!("{} changed", query.iter().count());657/// }658///659/// fn how_many_changed_2(query: Query<Ref<MyComponent>>) {660/// println!("{} changed", query.iter().filter(|c| c.is_changed()).count());661/// }662/// ```663pub struct Ref<'w, T: ?Sized> {664pub(crate) value: &'w T,665pub(crate) ticks: ComponentTicksRef<'w>,666}667668impl<'w, T: ?Sized> Ref<'w, T> {669/// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.670pub fn into_inner(self) -> &'w T {671self.value672}673674/// Map `Ref` to a different type using `f`.675///676/// This doesn't do anything else than call `f` on the wrapped value.677/// This is equivalent to [`Mut::map_unchanged`].678pub fn map<U: ?Sized>(self, f: impl FnOnce(&T) -> &U) -> Ref<'w, U> {679Ref {680value: f(self.value),681ticks: self.ticks,682}683}684685/// Create a new `Ref` using provided values.686///687/// This is an advanced feature, `Ref`s are designed to be _created_ by688/// engine-internal code and _consumed_ by end-user code.689///690/// - `value` - The value wrapped by `Ref`.691/// - `added` - A [`Tick`] that stores the tick when the wrapped value was created.692/// - `changed` - A [`Tick`] that stores the last time the wrapped value was changed.693/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used694/// as a reference to determine whether the wrapped value is newly added or changed.695/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".696pub fn new(697value: &'w T,698added: &'w Tick,699changed: &'w Tick,700last_run: Tick,701this_run: Tick,702caller: MaybeLocation<&'w &'static Location<'static>>,703) -> Ref<'w, T> {704Ref {705value,706ticks: ComponentTicksRef {707added,708changed,709changed_by: caller,710last_run,711this_run,712},713}714}715716/// Overwrite the `last_run` and `this_run` tick that are used for change detection.717///718/// This is an advanced feature. `Ref`s are usually _created_ by engine-internal code and719/// _consumed_ by end-user code.720pub fn set_ticks(&mut self, last_run: Tick, this_run: Tick) {721self.ticks.last_run = last_run;722self.ticks.this_run = this_run;723}724}725726/// Contiguous equivalent of [`Ref<T>`].727///728/// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous) for [`Ref<T>`].729#[derive(Clone)]730pub struct ContiguousRef<'w, T> {731pub(crate) value: &'w [T],732pub(crate) ticks: ContiguousComponentTicksRef<'w>,733}734735impl<'w, T> ContiguousRef<'w, T> {736/// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.737pub fn into_inner(self) -> &'w [T] {738self.value739}740741/// Returns the added ticks.742#[inline]743pub fn added_ticks_slice(&self) -> &'w [Tick] {744self.ticks.added745}746747/// Returns the changed ticks.748#[inline]749pub fn changed_ticks_slice(&self) -> &'w [Tick] {750self.ticks.changed751}752753/// Returns the changed by ticks.754#[inline]755pub fn changed_by_ticks_slice(&self) -> MaybeLocation<&[&'static Location<'static>]> {756self.ticks.changed_by.as_deref()757}758759/// Returns the tick when the system last ran.760#[inline]761pub fn last_run_tick(&self) -> Tick {762self.ticks.last_run763}764765/// Returns the tick of the system's current run.766#[inline]767pub fn this_run_tick(&self) -> Tick {768self.ticks.this_run769}770771/// Creates a new `ContiguousRef` using provided values or returns [`None`] if lengths of772/// `value`, `added`, `changed` and `changed_by` do not match773///774/// This is an advanced feature, `ContiguousRef`s are designed to be _created_ by775/// engine-internal code and _consumed_ by end-user code.776///777/// - `value` - The values wrapped by `ContiguousRef`.778/// - `added` - [`Tick`]s that store the tick when the wrapped value was created.779/// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.780/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used781/// as a reference to determine whether the wrapped value is newly added or changed.782/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".783/// - `caller` - [`Location`]s that store the location when the wrapper value was changed.784pub fn new(785value: &'w [T],786added: &'w [Tick],787changed: &'w [Tick],788last_run: Tick,789this_run: Tick,790caller: MaybeLocation<&'w [&'static Location<'static>]>,791) -> Option<Self> {792(value.len() == added.len())793.then(|| ContiguousComponentTicksRef::new(added, changed, last_run, this_run, caller))794.flatten()795.map(|ticks| Self { value, ticks })796}797798/// Splits [`ContiguousRef`] into it's inner data types.799pub fn split(this: Self) -> (&'w [T], ContiguousComponentTicksRef<'w>) {800(this.value, this.ticks)801}802803/// Reverse of [`ContiguousRef::split`], constructing a [`ContiguousRef`] using components'804/// values and ticks.805///806/// Returns [`None`] if lengths of `value` and `ticks` do not match, which doesn't happen if807/// `ticks` and `value` come from the same [`Self::split`] call.808pub fn from_parts(value: &'w [T], ticks: ContiguousComponentTicksRef<'w>) -> Option<Self> {809(value.len() == ticks.changed.len()).then_some(Self { value, ticks })810}811}812813impl<'w, T> Deref for ContiguousRef<'w, T> {814type Target = [T];815816#[inline]817fn deref(&self) -> &Self::Target {818self.value819}820}821822impl<'w, T> AsRef<[T]> for ContiguousRef<'w, T> {823#[inline]824fn as_ref(&self) -> &[T] {825self.deref()826}827}828829impl<'w, T> IntoIterator for ContiguousRef<'w, T> {830type Item = &'w T;831832type IntoIter = core::slice::Iter<'w, T>;833834fn into_iter(self) -> Self::IntoIter {835self.value.iter()836}837}838839impl<'w, T: core::fmt::Debug> core::fmt::Debug for ContiguousRef<'w, T> {840fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {841f.debug_tuple("ContiguousRef").field(&self.value).finish()842}843}844845impl<'w, 'a, T> IntoIterator for &'a Ref<'w, T>846where847&'a T: IntoIterator,848{849type Item = <&'a T as IntoIterator>::Item;850type IntoIter = <&'a T as IntoIterator>::IntoIter;851852fn into_iter(self) -> Self::IntoIter {853self.value.into_iter()854}855}856change_detection_impl!(Ref<'w, T>, T,);857impl_debug!(Ref<'w, T>,);858859/// Unique mutable borrow of an entity's component or of a resource.860///861/// This can be used in queries to access change detection from immutable query methods, as opposed862/// to `&mut T` which only provides access to change detection from mutable query methods.863///864/// ```rust865/// # use bevy_ecs::prelude::*;866/// # use bevy_ecs::query::QueryData;867/// #868/// #[derive(Component, Clone, Debug)]869/// struct Name(String);870///871/// #[derive(Component, Clone, Copy, Debug)]872/// struct Health(f32);873///874/// fn my_system(mut query: Query<(Mut<Name>, &mut Health)>) {875/// // Mutable access provides change detection information for both parameters:876/// // - `name` has type `Mut<Name>`877/// // - `health` has type `Mut<Health>`878/// for (name, health) in query.iter_mut() {879/// println!("Name: {:?} (last changed {:?})", name, name.last_changed());880/// println!("Health: {:?} (last changed: {:?})", health, health.last_changed());881/// # println!("{}{}", name.0, health.0); // Silence dead_code warning882/// }883///884/// // Immutable access only provides change detection for `Name`:885/// // - `name` has type `Ref<Name>`886/// // - `health` has type `&Health`887/// for (name, health) in query.iter() {888/// println!("Name: {:?} (last changed {:?})", name, name.last_changed());889/// println!("Health: {:?}", health);890/// }891/// }892///893/// # bevy_ecs::system::assert_is_system(my_system);894/// ```895pub struct Mut<'w, T: ?Sized> {896pub(crate) value: &'w mut T,897pub(crate) ticks: ComponentTicksMut<'w>,898}899900impl<'w, T: ?Sized> Mut<'w, T> {901/// Creates a new change-detection enabled smart pointer.902/// In almost all cases you do not need to call this method manually,903/// as instances of `Mut` will be created by engine-internal code.904///905/// Many use-cases of this method would be better served by [`Mut::map_unchanged`]906/// or [`Mut::reborrow`].907///908/// - `value` - The value wrapped by this smart pointer.909/// - `added` - A [`Tick`] that stores the tick when the wrapped value was created.910/// - `last_changed` - A [`Tick`] that stores the last time the wrapped value was changed.911/// This will be updated to the value of `change_tick` if the returned smart pointer912/// is modified.913/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used914/// as a reference to determine whether the wrapped value is newly added or changed.915/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".916pub fn new(917value: &'w mut T,918added: &'w mut Tick,919last_changed: &'w mut Tick,920last_run: Tick,921this_run: Tick,922caller: MaybeLocation<&'w mut &'static Location<'static>>,923) -> Self {924Self {925value,926ticks: ComponentTicksMut {927added,928changed: last_changed,929changed_by: caller,930last_run,931this_run,932},933}934}935936/// Overwrite the `last_run` and `this_run` tick that are used for change detection.937///938/// This is an advanced feature. `Mut`s are usually _created_ by engine-internal code and939/// _consumed_ by end-user code.940pub fn set_ticks(&mut self, last_run: Tick, this_run: Tick) {941self.ticks.last_run = last_run;942self.ticks.this_run = this_run;943}944}945946/// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous)947/// for [`Mut<T>`] and `&mut T`948///949/// # Warning950/// Implementations of [`DerefMut`], [`AsMut`] and [`IntoIterator`] update change ticks, which may effect performance.951pub struct ContiguousMut<'w, T> {952pub(crate) value: &'w mut [T],953pub(crate) ticks: ContiguousComponentTicksMut<'w>,954}955956impl<'w, T> ContiguousMut<'w, T> {957/// Manually bypasses change detection, allowing you to mutate the underlying values without updating the change tick,958/// which may be useful to reduce amount of work to be done.959///960/// # Warning961/// This is a risky operation, that can have unexpected consequences on any system relying on this code.962/// However, it can be an essential escape hatch when, for example,963/// you are trying to synchronize representations using change detection and need to avoid infinite recursion.964#[inline]965pub fn bypass_change_detection(&mut self) -> &mut [T] {966self.value967}968969/// Returns the immutable added ticks' slice.970#[inline]971pub fn added_ticks_slice(&self) -> &[Tick] {972self.ticks.added973}974975/// Returns the immutable changed ticks' slice.976#[inline]977pub fn changed_ticks_slice(&self) -> &[Tick] {978self.ticks.changed979}980981/// Returns the mutable changed by ticks' slice982#[inline]983pub fn changed_by_ticks_mut(&self) -> MaybeLocation<&[&'static Location<'static>]> {984self.ticks.changed_by.as_deref()985}986987/// Returns the tick when the system last ran.988#[inline]989pub fn last_run_tick(&self) -> Tick {990self.ticks.last_run991}992993/// Returns the tick of the system's current run.994#[inline]995pub fn this_run_tick(&self) -> Tick {996self.ticks.this_run997}998999/// Returns the mutable added ticks' slice.1000#[inline]1001pub fn added_ticks_slice_mut(&mut self) -> &mut [Tick] {1002self.ticks.added1003}10041005/// Returns the mutable changed ticks' slice.1006#[inline]1007pub fn changed_ticks_slice_mut(&mut self) -> &mut [Tick] {1008self.ticks.changed1009}10101011/// Returns the mutable changed by ticks' slice1012#[inline]1013pub fn changed_by_ticks_slice_mut(1014&mut self,1015) -> MaybeLocation<&mut [&'static Location<'static>]> {1016self.ticks.changed_by.as_deref_mut()1017}10181019/// Marks all components as changed.1020///1021/// **Runs in O(n), where n is the amount of rows**1022#[inline]1023pub fn mark_all_as_changed(&mut self) {1024self.ticks.mark_all_as_changed();1025}10261027/// Creates a new `ContiguousMut` using provided values or returns [`None`] if lengths of1028/// `value`, `added`, `changed` and `changed_by` do not match1029///1030/// This is an advanced feature, `ContiguousMut`s are designed to be _created_ by1031/// engine-internal code and _consumed_ by end-user code.1032///1033/// - `value` - The values wrapped by `ContiguousMut`.1034/// - `added` - [`Tick`]s that store the tick when the wrapped value was created.1035/// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.1036/// - `last_run` - A [`Tick`], occurring before `this_run`, which is used1037/// as a reference to determine whether the wrapped value is newly added or changed.1038/// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".1039/// - `caller` - [`Location`]s that store the location when the wrapper value was changed.1040pub fn new(1041value: &'w mut [T],1042added: &'w mut [Tick],1043changed: &'w mut [Tick],1044last_run: Tick,1045this_run: Tick,1046caller: MaybeLocation<&'w mut [&'static Location<'static>]>,1047) -> Option<Self> {1048(value.len() == added.len())1049.then(|| ContiguousComponentTicksMut::new(added, changed, last_run, this_run, caller))1050.flatten()1051.map(|ticks| Self { value, ticks })1052}10531054/// Returns a `ContiguousMut<T>` with a smaller lifetime.1055pub fn reborrow(&mut self) -> ContiguousMut<'_, T> {1056ContiguousMut {1057value: self.value,1058ticks: self.ticks.reborrow(),1059}1060}10611062/// Splits [`ContiguousMut`] into it's inner data types. It may be useful, when you want to1063/// have an iterator over component values and check ticks simultaneously (using1064/// [`ContiguousComponentTicksMut::is_changed_iter`] and1065/// [`ContiguousComponentTicksMut::is_added_iter`]).1066///1067/// Variant of [`Self::split`] which bypasses change detection: [`Self::bypass_change_detection_split`].1068///1069/// Reverse of [`Self::split`] is [`Self::from_parts`].1070///1071/// # Warning1072/// This version updates changed ticks **before** returning, hence1073/// [`ContiguousComponentTicksMut::is_changed_iter`] will be useless (the iterator will be filled with1074/// [`prim@true`]s).1075// NOTE: `ticks_since_insert` will be 0 (because `this.mark_all_as_changed` makes all changed ticks `this_run`),1076// `ticks_since_system` won't be 0, `tick` is newer if1077// `ticks_since_system` > `ticks_since_insert`, hence it will always be true.1078pub fn split(mut this: Self) -> (&'w mut [T], ContiguousComponentTicksMut<'w>) {1079this.mark_all_as_changed();1080(this.value, this.ticks)1081}10821083/// Splits [`ContiguousMut`] into it's inner data types. It may be useful, when you want to1084/// have an iterator over component values and check ticks simultaneously (using1085/// [`ContiguousComponentTicksMut::is_changed_iter`] and1086/// [`ContiguousComponentTicksMut::is_added_iter`]).1087///1088/// Variant of [`Self::bypass_change_detection_split`] which **does not** bypass change detection: [`Self::split`].1089///1090/// Reverse of [`Self::bypass_change_detection_split`] is [`Self::from_parts`].1091///1092/// # Warning1093/// **Bypasses change detection**, call [`Self::split`] if you don't want to bypass it.1094///1095/// See [`Self::bypass_change_detection`] for further explanations.1096pub fn bypass_change_detection_split(1097this: Self,1098) -> (&'w mut [T], ContiguousComponentTicksMut<'w>) {1099(this.value, this.ticks)1100}11011102/// Reverse of [`ContiguousMut::split`] and [`ContiguousMut::bypass_change_detection_split`],1103/// constructing a [`ContiguousMut`] using components' values and ticks.1104///1105/// Returns [`None`] if lengths of `value` and `ticks` do not match, which doesn't happen if1106/// `ticks` and `value` come from the same [`Self::split`] or [`Self::bypass_change_detection_split`] call.1107pub fn from_parts(value: &'w mut [T], ticks: ContiguousComponentTicksMut<'w>) -> Option<Self> {1108(value.len() == ticks.changed.len()).then_some(Self { value, ticks })1109}1110}11111112impl<'w, T> Deref for ContiguousMut<'w, T> {1113type Target = [T];11141115#[inline]1116fn deref(&self) -> &Self::Target {1117self.value1118}1119}11201121impl<'w, T> DerefMut for ContiguousMut<'w, T> {1122#[inline]1123fn deref_mut(&mut self) -> &mut Self::Target {1124self.mark_all_as_changed();1125self.value1126}1127}11281129impl<'w, T> AsRef<[T]> for ContiguousMut<'w, T> {1130#[inline]1131fn as_ref(&self) -> &[T] {1132self.deref()1133}1134}11351136impl<'w, T> AsMut<[T]> for ContiguousMut<'w, T> {1137#[inline]1138fn as_mut(&mut self) -> &mut [T] {1139self.deref_mut()1140}1141}11421143impl<'w, T> IntoIterator for ContiguousMut<'w, T> {1144type Item = &'w mut T;11451146type IntoIter = core::slice::IterMut<'w, T>;11471148fn into_iter(mut self) -> Self::IntoIter {1149self.mark_all_as_changed();1150self.value.iter_mut()1151}1152}11531154impl<'w, T: core::fmt::Debug> core::fmt::Debug for ContiguousMut<'w, T> {1155fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {1156f.debug_tuple("ContiguousMut").field(&self.value).finish()1157}1158}11591160impl<'w, T> From<ContiguousMut<'w, T>> for ContiguousRef<'w, T> {1161fn from(value: ContiguousMut<'w, T>) -> Self {1162Self {1163value: value.value,1164ticks: value.ticks.into(),1165}1166}1167}11681169impl<'w, T: ?Sized> From<Mut<'w, T>> for Ref<'w, T> {1170fn from(mut_ref: Mut<'w, T>) -> Self {1171Self {1172value: mut_ref.value,1173ticks: mut_ref.ticks.into(),1174}1175}1176}11771178impl<'w, 'a, T> IntoIterator for &'a Mut<'w, T>1179where1180&'a T: IntoIterator,1181{1182type Item = <&'a T as IntoIterator>::Item;1183type IntoIter = <&'a T as IntoIterator>::IntoIter;11841185fn into_iter(self) -> Self::IntoIter {1186self.value.into_iter()1187}1188}11891190impl<'w, 'a, T> IntoIterator for &'a mut Mut<'w, T>1191where1192&'a mut T: IntoIterator,1193{1194type Item = <&'a mut T as IntoIterator>::Item;1195type IntoIter = <&'a mut T as IntoIterator>::IntoIter;11961197fn into_iter(self) -> Self::IntoIter {1198self.set_changed();1199self.value.into_iter()1200}1201}12021203change_detection_impl!(Mut<'w, T>, T,);1204change_detection_mut_impl!(Mut<'w, T>, T,);1205impl_methods!(Mut<'w, T>, T,);1206impl_debug!(Mut<'w, T>,);12071208/// Unique mutable borrow of resources or an entity's component.1209///1210/// Similar to [`Mut`], but not generic over the component type, instead1211/// exposing the raw pointer as a `*mut ()`.1212///1213/// Usually you don't need to use this and can instead use the APIs returning a1214/// [`Mut`], but in situations where the types are not known at compile time1215/// or are defined outside of rust this can be used.1216pub struct MutUntyped<'w> {1217pub(crate) value: PtrMut<'w>,1218pub(crate) ticks: ComponentTicksMut<'w>,1219}12201221impl<'w> MutUntyped<'w> {1222/// Returns the pointer to the value, marking it as changed.1223///1224/// In order to avoid marking the value as changed, you need to call [`bypass_change_detection`](DetectChangesMut::bypass_change_detection).1225#[inline]1226pub fn into_inner(mut self) -> PtrMut<'w> {1227self.set_changed();1228self.value1229}12301231/// Returns a [`MutUntyped`] with a smaller lifetime.1232/// This is useful if you have `&mut MutUntyped`, but you need a `MutUntyped`.1233#[inline]1234pub fn reborrow(&mut self) -> MutUntyped<'_> {1235MutUntyped {1236value: self.value.reborrow(),1237ticks: ComponentTicksMut {1238added: self.ticks.added,1239changed: self.ticks.changed,1240changed_by: self.ticks.changed_by.as_deref_mut(),1241last_run: self.ticks.last_run,1242this_run: self.ticks.this_run,1243},1244}1245}12461247/// Returns `true` if this value was changed or mutably dereferenced1248/// either since a specific change tick.1249pub fn has_changed_since(&self, tick: Tick) -> bool {1250self.ticks.changed.is_newer_than(tick, self.ticks.this_run)1251}12521253/// Returns a pointer to the value without taking ownership of this smart pointer, marking it as changed.1254///1255/// In order to avoid marking the value as changed, you need to call [`bypass_change_detection`](DetectChangesMut::bypass_change_detection).1256#[inline]1257pub fn as_mut(&mut self) -> PtrMut<'_> {1258self.set_changed();1259self.value.reborrow()1260}12611262/// Returns an immutable pointer to the value without taking ownership.1263#[inline]1264pub fn as_ref(&self) -> Ptr<'_> {1265self.value.as_ref()1266}12671268/// Turn this [`MutUntyped`] into a [`Mut`] by mapping the inner [`PtrMut`] to another value,1269/// without flagging a change.1270/// This function is the untyped equivalent of [`Mut::map_unchanged`].1271///1272/// You should never modify the argument passed to the closure – if you want to modify the data without flagging a change, consider using [`bypass_change_detection`](DetectChangesMut::bypass_change_detection) to make your intent explicit.1273///1274/// If you know the type of the value you can do1275/// ```no_run1276/// # use bevy_ecs::change_detection::{Mut, MutUntyped};1277/// # let mut_untyped: MutUntyped = unimplemented!();1278/// // SAFETY: ptr is of type `u8`1279/// mut_untyped.map_unchanged(|ptr| unsafe { ptr.deref_mut::<u8>() });1280/// ```1281/// If you have a [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr) that you know belongs to this [`MutUntyped`],1282/// you can do1283/// ```no_run1284/// # use bevy_ecs::change_detection::{Mut, MutUntyped};1285/// # let mut_untyped: MutUntyped = unimplemented!();1286/// # let reflect_from_ptr: bevy_reflect::ReflectFromPtr = unimplemented!();1287/// // SAFETY: from the context it is known that `ReflectFromPtr` was made for the type of the `MutUntyped`1288/// mut_untyped.map_unchanged(|ptr| unsafe { reflect_from_ptr.as_reflect_mut(ptr) });1289/// ```1290pub fn map_unchanged<T: ?Sized>(self, f: impl FnOnce(PtrMut<'w>) -> &'w mut T) -> Mut<'w, T> {1291Mut {1292value: f(self.value),1293ticks: self.ticks,1294}1295}12961297/// Transforms this [`MutUntyped`] into a [`Mut<T>`] with the same lifetime.1298///1299/// # Safety1300/// - `T` must be the erased pointee type for this [`MutUntyped`].1301pub unsafe fn with_type<T>(self) -> Mut<'w, T> {1302Mut {1303// SAFETY: `value` is `Aligned` and caller ensures the pointee type is `T`.1304value: unsafe { self.value.deref_mut() },1305ticks: self.ticks,1306}1307}1308}13091310impl<'w> DetectChanges for MutUntyped<'w> {1311#[inline]1312fn is_added(&self) -> bool {1313self.ticks1314.added1315.is_newer_than(self.ticks.last_run, self.ticks.this_run)1316}13171318#[inline]1319fn is_changed(&self) -> bool {1320self.ticks1321.changed1322.is_newer_than(self.ticks.last_run, self.ticks.this_run)1323}13241325#[inline]1326fn last_changed(&self) -> Tick {1327*self.ticks.changed1328}13291330#[inline]1331fn changed_by(&self) -> MaybeLocation {1332self.ticks.changed_by.copied()1333}13341335#[inline]1336fn added(&self) -> Tick {1337*self.ticks.added1338}1339}13401341impl<'w> DetectChangesMut for MutUntyped<'w> {1342type Inner = PtrMut<'w>;13431344#[inline]1345#[track_caller]1346fn set_changed(&mut self) {1347*self.ticks.changed = self.ticks.this_run;1348self.ticks.changed_by.assign(MaybeLocation::caller());1349}13501351#[inline]1352#[track_caller]1353fn set_added(&mut self) {1354*self.ticks.changed = self.ticks.this_run;1355*self.ticks.added = self.ticks.this_run;1356self.ticks.changed_by.assign(MaybeLocation::caller());1357}13581359#[inline]1360#[track_caller]1361fn set_last_changed(&mut self, last_changed: Tick) {1362*self.ticks.changed = last_changed;1363self.ticks.changed_by.assign(MaybeLocation::caller());1364}13651366#[inline]1367#[track_caller]1368fn set_last_added(&mut self, last_added: Tick) {1369*self.ticks.added = last_added;1370*self.ticks.changed = last_added;1371self.ticks.changed_by.assign(MaybeLocation::caller());1372}13731374#[inline]1375#[track_caller]1376fn bypass_change_detection(&mut self) -> &mut Self::Inner {1377&mut self.value1378}1379}13801381impl core::fmt::Debug for MutUntyped<'_> {1382fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {1383f.debug_tuple("MutUntyped")1384.field(&self.value.as_ptr())1385.finish()1386}1387}13881389impl<'w, T> From<Mut<'w, T>> for MutUntyped<'w> {1390fn from(value: Mut<'w, T>) -> Self {1391MutUntyped {1392value: value.value.into(),1393ticks: value.ticks,1394}1395}1396}139713981399