Skip to main content

bevy_ecs/change_detection/
params.rs

1use crate::{
2    change_detection::{traits::*, AtomicTick, ComponentTickCells, MaybeLocation, Tick},
3    component::Mutable,
4    ptr::PtrMut,
5    resource::Resource,
6};
7use bevy_ptr::{Ptr, ThinSlicePtr, UnsafeCellDeref};
8use core::{
9    cell::UnsafeCell,
10    ops::{Deref, DerefMut, Range},
11    panic::Location,
12};
13
14/// Used by immutable query parameters (such as [`Ref`] and [`Res`])
15/// to store immutable access to the [`Tick`]s of a single component or resource.
16#[derive(Clone, Copy)]
17pub(crate) struct ComponentTicksRef<'w> {
18    pub(crate) added: &'w Tick,
19    pub(crate) changed: &'w Tick,
20    pub(crate) changed_by: MaybeLocation<&'w &'static Location<'static>>,
21    pub(crate) last_run: Tick,
22    pub(crate) this_run: Tick,
23}
24
25impl<'w> ComponentTicksRef<'w> {
26    /// # Safety
27    /// This should never alias the underlying ticks with a mutable one such as `ComponentTicksMut`.
28    #[inline]
29    pub(crate) unsafe fn from_tick_cells(
30        cells: ComponentTickCells<'w>,
31        last_run: Tick,
32        this_run: Tick,
33    ) -> Self {
34        Self {
35            // SAFETY: Caller ensures there is no mutable access to the cell.
36            added: unsafe { cells.added.deref() },
37            // SAFETY: Caller ensures there is no mutable access to the cell.
38            changed: unsafe { cells.changed.deref() },
39            // SAFETY: Caller ensures there is no mutable access to the cell.
40            changed_by: unsafe { cells.changed_by.map(|changed_by| changed_by.deref()) },
41            last_run,
42            this_run,
43        }
44    }
45}
46
47/// Data type storing contiguously lying ticks.
48///
49/// Retrievable via [`ContiguousRef::split`] and probably only useful if you want to use the following
50/// methods:
51/// - [`ContiguousComponentTicksRef::is_changed_iter`],
52/// - [`ContiguousComponentTicksRef::is_added_iter`]
53#[derive(Clone)]
54pub struct ContiguousComponentTicksRef<'w> {
55    pub(crate) added: &'w [Tick],
56    pub(crate) changed: &'w [Tick],
57    pub(crate) changed_by: MaybeLocation<&'w [&'static Location<'static>]>,
58    pub(crate) last_run: Tick,
59    pub(crate) this_run: Tick,
60    pub(crate) summary_tick: Option<&'w AtomicTick>,
61}
62
63impl<'w> ContiguousComponentTicksRef<'w> {
64    /// # Safety
65    /// - The caller must have permission for all given ticks to be read.
66    /// - `len` must be the length of `added`, `changed` and `changed_by` (unless none) slices.
67    /// - `range` must specify an in-bounds slice of the table rows.
68    /// - `range.start` must be less than or equal to `range.end`.
69    pub(crate) unsafe fn from_slice_ptrs(
70        added: ThinSlicePtr<'w, UnsafeCell<Tick>>,
71        changed: ThinSlicePtr<'w, UnsafeCell<Tick>>,
72        summary_tick: Option<&'w AtomicTick>,
73        changed_by: MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
74        range: Range<usize>,
75        this_run: Tick,
76        last_run: Tick,
77    ) -> Self {
78        Self {
79            // SAFETY:
80            // - The caller ensures that `len` is the length of the slice.
81            // - The caller ensures we have permission to read the data.
82            // - The caller ensures that `range` specifies an in-bounds slice of
83            //   the table rows.
84            // - The caller ensures that `range.start` is less than or equal to
85            //   `range.end`.
86            added: unsafe { added.cast().slice_unchecked(range.clone()) },
87            // SAFETY: see above.
88            changed: unsafe { changed.cast().slice_unchecked(range.clone()) },
89            summary_tick,
90            // SAFETY: see above.
91            changed_by: changed_by.map(|v| unsafe { v.cast().slice_unchecked(range) }),
92            last_run,
93            this_run,
94        }
95    }
96
97    /// Creates a new `ContiguousComponentTicksRef` using provided values or returns [`None`] if lengths of
98    /// `added`, `changed` and `changed_by` do not match    
99    ///
100    /// This is an advanced feature, `ContiguousComponentTicksRef`s are designed to be _created_ by
101    /// engine-internal code and _consumed_ by end-user code.
102    ///
103    /// - `added` - [`Tick`]s that store the tick when the wrapped value was created.
104    /// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.
105    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
106    ///   as a reference to determine whether the wrapped value is newly added or changed.
107    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
108    /// - `caller` - [`Location`]s that store the location when the wrapper value was changed.
109    pub fn new(
110        added: &'w [Tick],
111        changed: &'w [Tick],
112        summary_tick: Option<&'w AtomicTick>,
113        last_run: Tick,
114        this_run: Tick,
115        caller: MaybeLocation<&'w [&'static Location<'static>]>,
116    ) -> Option<Self> {
117        let eq = added.len() == changed.len()
118            && caller
119                .map(|v| v.len() == added.len())
120                .into_option()
121                .unwrap_or(true);
122        eq.then_some(Self {
123            added,
124            changed,
125            summary_tick,
126            changed_by: caller,
127            last_run,
128            this_run,
129        })
130    }
131
132    /// Returns added ticks' slice.
133    pub fn added(&self) -> &'w [Tick] {
134        self.added
135    }
136
137    /// Returns changed ticks' slice.
138    pub fn changed(&self) -> &'w [Tick] {
139        self.changed
140    }
141
142    /// Returns changed by locations' slice.
143    pub fn changed_by(&self) -> MaybeLocation<&[&'static Location<'static>]> {
144        self.changed_by.as_deref()
145    }
146
147    /// Returns the tick the system last ran.
148    pub fn last_run(&self) -> Tick {
149        self.last_run
150    }
151
152    /// Returns the tick of the current system's run.
153    pub fn this_run(&self) -> Tick {
154        self.this_run
155    }
156
157    /// Returns an iterator where the i-th item corresponds to whether the i-th component was
158    /// marked as changed. If the value equals [`prim@true`], then the component was changed.
159    ///
160    /// # Example
161    /// ```
162    /// # use bevy_ecs::prelude::*;
163    /// #
164    /// # #[derive(Component)]
165    /// # struct A(pub i32);
166    ///
167    /// fn some_system(mut query: Query<Ref<A>>) {
168    ///     for a in query.contiguous_iter().unwrap() {
169    ///         let (a_values, a_ticks) = ContiguousRef::split(a);
170    ///         for (value, is_changed) in a_values.iter().zip(a_ticks.is_changed_iter()) {
171    ///             if is_changed {
172    ///                 // do something
173    ///             }
174    ///         }
175    ///     }
176    /// }
177    /// ```
178    pub fn is_changed_iter(&self) -> impl Iterator<Item = bool> {
179        self.changed
180            .iter()
181            .map(|v| v.is_newer_than(self.last_run, self.this_run))
182    }
183
184    /// Returns an iterator where the i-th item corresponds to whether the i-th component was
185    /// marked as added. If the value equals [`prim@true`], then the component was added.
186    ///
187    /// # Example
188    /// ```
189    /// # use bevy_ecs::prelude::*;
190    /// #
191    /// # #[derive(Component)]
192    /// # struct A(pub i32);
193    ///
194    /// fn some_system(mut query: Query<Ref<A>>) {
195    ///     for a in query.contiguous_iter().unwrap() {
196    ///         let (a_values, a_ticks) = ContiguousRef::split(a);
197    ///         for (value, is_added) in a_values.iter().zip(a_ticks.is_added_iter()) {
198    ///             if is_added {
199    ///                 // do something
200    ///             }
201    ///         }
202    ///     }
203    /// }
204    /// ```
205    pub fn is_added_iter(&self) -> impl Iterator<Item = bool> {
206        self.added
207            .iter()
208            .map(|v| v.is_newer_than(self.last_run, self.this_run))
209    }
210
211    /// Narrows the range of rows that this set of ticks represents.
212    ///
213    /// If the range is out of range, this method will panic.
214    pub fn slice(self, range: Range<u32>) -> Self {
215        Self {
216            added: &self.added[(range.start as usize)..(range.end as usize)],
217            changed: &self.changed[(range.start as usize)..(range.end as usize)],
218            changed_by: self
219                .changed_by
220                .map(|changed_by| &changed_by[(range.start as usize)..(range.end as usize)]),
221            last_run: self.last_run,
222            this_run: self.this_run,
223            summary_tick: self.summary_tick,
224        }
225    }
226
227    /// Returns `Some(true)` if this component has a summary tick and any
228    /// component in this column may have been changed since the last time the
229    /// associated query ran.
230    ///
231    /// If the component has no summary tick, this method returns `None`. If
232    /// there is a summary tick, but there has been no change since the last
233    /// time the query ran, this method returns `Some(false)`.
234    pub fn summary_tick_is_changed(&self) -> Option<bool> {
235        self.summary_tick.map(|summary_tick| {
236            summary_tick
237                .get()
238                .is_newer_than(self.last_run, self.this_run)
239        })
240    }
241}
242
243/// Used by mutable query parameters (such as [`Mut`] and [`ResMut`])
244/// to store mutable access to the [`Tick`]s of a single component or resource.
245pub(crate) struct ComponentTicksMut<'w> {
246    pub(crate) added: &'w mut Tick,
247    pub(crate) changed: &'w mut Tick,
248    pub(crate) changed_by: MaybeLocation<&'w mut &'static Location<'static>>,
249    pub(crate) last_run: Tick,
250    pub(crate) this_run: Tick,
251    /// A reference to the summary tick for the component, if the component is
252    /// dense and has a summary tick.
253    pub(crate) summary_tick: Option<&'w AtomicTick>,
254}
255
256impl<'w> ComponentTicksMut<'w> {
257    /// # Safety
258    /// This should never alias the underlying ticks. All access must be unique.
259    #[inline]
260    pub(crate) unsafe fn from_tick_cells(
261        cells: ComponentTickCells<'w>,
262        last_run: Tick,
263        this_run: Tick,
264    ) -> Self {
265        Self {
266            // SAFETY: Caller ensures there is no alias to the cell.
267            added: unsafe { cells.added.deref_mut() },
268            // SAFETY: Caller ensures there is no alias to the cell.
269            changed: unsafe { cells.changed.deref_mut() },
270            // SAFETY: Caller ensures there is no alias to the cell.
271            changed_by: unsafe { cells.changed_by.map(|changed_by| changed_by.deref_mut()) },
272            last_run,
273            this_run,
274            summary_tick: cells.summary_tick,
275        }
276    }
277}
278
279impl<'w> From<ComponentTicksMut<'w>> for ComponentTicksRef<'w> {
280    fn from(ticks: ComponentTicksMut<'w>) -> Self {
281        ComponentTicksRef {
282            added: ticks.added,
283            changed: ticks.changed,
284            changed_by: ticks.changed_by.map(|changed_by| &*changed_by),
285            last_run: ticks.last_run,
286            this_run: ticks.this_run,
287        }
288    }
289}
290
291/// Data type storing contiguously lying ticks, which may be accessed to mutate.
292///
293/// Retrievable via [`ContiguousMut::split`] and probably only useful if you want to use the following
294/// methods:
295/// - [`ContiguousComponentTicksMut::is_changed_iter`],
296/// - [`ContiguousComponentTicksMut::is_added_iter`]
297pub struct ContiguousComponentTicksMut<'w> {
298    pub(crate) added: &'w mut [Tick],
299    pub(crate) changed: &'w mut [Tick],
300    pub(crate) changed_by: MaybeLocation<&'w mut [&'static Location<'static>]>,
301    pub(crate) last_run: Tick,
302    pub(crate) this_run: Tick,
303    pub(crate) summary_tick: Option<&'w AtomicTick>,
304}
305
306impl<'w> ContiguousComponentTicksMut<'w> {
307    /// # Safety
308    /// - The caller must have permission to use all given ticks to be mutated.
309    /// - `len` must be the length of `added`, `changed` and `changed_by` (unless none) slices.
310    /// - `range` must specify an in-bounds slice of the table rows.
311    /// - `range.start` must be less than or equal to `range.end`.
312    pub(crate) unsafe fn from_slice_ptrs(
313        added: ThinSlicePtr<'w, UnsafeCell<Tick>>,
314        changed: ThinSlicePtr<'w, UnsafeCell<Tick>>,
315        summary_tick: Option<&'w AtomicTick>,
316        changed_by: MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
317        range: Range<usize>,
318        this_run: Tick,
319        last_run: Tick,
320    ) -> Self {
321        Self {
322            // SAFETY:
323            // - The caller ensures that `len` is the length of the slice.
324            // - The caller ensures we have permission to mutate the data.
325            // - The caller ensures that `range` specifies an in-bounds slice of
326            //   the table rows.
327            // - The caller ensures that `range.start` is less than or equal to
328            //   `range.end`.
329            added: unsafe { added.slice_mut_unchecked(range.clone()) },
330            // SAFETY: see above.
331            changed: unsafe { changed.slice_mut_unchecked(range.clone()) },
332            summary_tick,
333            // SAFETY: see above.
334            changed_by: changed_by.map(|v| unsafe { v.slice_mut_unchecked(range) }),
335            last_run,
336            this_run,
337        }
338    }
339
340    /// Creates a new `ContiguousComponentTicksMut` using provided values or returns [`None`] if lengths of
341    /// `added`, `changed` and `changed_by` do not match    
342    ///
343    /// This is an advanced feature, `ContiguousComponentTicksMut`s are designed to be _created_ by
344    /// engine-internal code and _consumed_ by end-user code.
345    ///
346    /// - `added` - [`Tick`]s that store the tick when the wrapped value was created.
347    /// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.
348    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
349    ///   as a reference to determine whether the wrapped value is newly added or changed.
350    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
351    /// - `caller` - [`Location`]s that store the location when the wrapper value was changed.
352    pub fn new(
353        added: &'w mut [Tick],
354        changed: &'w mut [Tick],
355        summary_tick: Option<&'w AtomicTick>,
356        last_run: Tick,
357        this_run: Tick,
358        caller: MaybeLocation<&'w mut [&'static Location<'static>]>,
359    ) -> Option<Self> {
360        let eq = added.len() == changed.len()
361            && caller
362                .as_ref()
363                .map(|v| v.len() == added.len())
364                .into_option()
365                .unwrap_or(true);
366        eq.then_some(Self {
367            added,
368            changed,
369            summary_tick,
370            changed_by: caller,
371            last_run,
372            this_run,
373        })
374    }
375
376    /// Returns added ticks' slice.
377    pub fn added(&self) -> &[Tick] {
378        self.added
379    }
380
381    /// Returns changed ticks' slice.
382    pub fn changed(&self) -> &[Tick] {
383        self.changed
384    }
385
386    /// Returns changed by locations' slice.
387    pub fn changed_by(&self) -> MaybeLocation<&[&'static Location<'static>]> {
388        self.changed_by.as_deref()
389    }
390
391    /// Returns mutable added ticks' slice.
392    pub fn added_mut(&mut self) -> &mut [Tick] {
393        self.added
394    }
395
396    /// Returns mutable changed ticks' slice.
397    pub fn changed_mut(&mut self) -> &mut [Tick] {
398        self.changed
399    }
400
401    /// Returns mutable changed by locations' slice.
402    pub fn changed_by_mut(&mut self) -> MaybeLocation<&mut [&'static Location<'static>]> {
403        self.changed_by.as_deref_mut()
404    }
405
406    /// Returns the tick the system last ran.
407    pub fn last_run(&self) -> Tick {
408        self.last_run
409    }
410
411    /// Returns the tick of the current system's run.
412    pub fn this_run(&self) -> Tick {
413        self.this_run
414    }
415
416    /// Returns an iterator where the i-th item corresponds to whether the i-th component was
417    /// marked as changed. If the value equals [`prim@true`], then the component was changed.
418    ///
419    /// # Example
420    /// ```
421    /// # use bevy_ecs::prelude::*;
422    /// #
423    /// # #[derive(Component)]
424    /// # struct A(pub i32);
425    ///
426    /// fn some_system(mut query: Query<&mut A>) {
427    ///     for a in query.contiguous_iter_mut().unwrap() {
428    ///         let (a_values, a_ticks) = ContiguousMut::split(a);
429    ///         for (value, is_changed) in a_values.iter_mut().zip(a_ticks.is_changed_iter()) {
430    ///             if is_changed {
431    ///                 value.0 *= 10;
432    ///             }
433    ///         }
434    ///     }
435    /// }
436    /// ```
437    pub fn is_changed_iter(&self) -> impl Iterator<Item = bool> {
438        self.changed
439            .iter()
440            .map(|v| v.is_newer_than(self.last_run, self.this_run))
441    }
442
443    /// Returns an iterator where the i-th item corresponds to whether the i-th component was
444    /// marked as added. If the value equals [`prim@true`], then the component was added.
445    ///
446    /// # Example
447    /// ```
448    /// # use bevy_ecs::prelude::*;
449    /// #
450    /// # #[derive(Component)]
451    /// # struct A(pub i32);
452    ///
453    /// fn some_system(mut query: Query<&mut A>) {
454    ///     for a in query.contiguous_iter_mut().unwrap() {
455    ///         let (a_values, a_ticks) = ContiguousMut::split(a);
456    ///         for (value, is_added) in a_values.iter_mut().zip(a_ticks.is_added_iter()) {
457    ///             if is_added {
458    ///                 value.0 = 10;
459    ///             }
460    ///         }
461    ///     }
462    /// }
463    /// ```
464    pub fn is_added_iter(&self) -> impl Iterator<Item = bool> {
465        self.added
466            .iter()
467            .map(|v| v.is_newer_than(self.last_run, self.this_run))
468    }
469
470    /// Marks every tick as changed.
471    pub fn mark_all_as_changed(&mut self) {
472        let this_run = self.this_run;
473
474        self.changed_by.as_mut().map(|v| {
475            for v in v.iter_mut() {
476                *v = Location::caller();
477            }
478        });
479
480        for t in self.changed.iter_mut() {
481            *t = this_run;
482        }
483
484        if let Some(summary_tick) = self.summary_tick {
485            summary_tick.set(this_run);
486        }
487    }
488
489    /// Returns a `ContiguousComponentTicksMut` with a smaller lifetime.
490    pub fn reborrow(&mut self) -> ContiguousComponentTicksMut<'_> {
491        ContiguousComponentTicksMut {
492            added: self.added,
493            changed: self.changed,
494            summary_tick: self.summary_tick,
495            changed_by: self.changed_by.as_deref_mut(),
496            last_run: self.last_run,
497            this_run: self.this_run,
498        }
499    }
500
501    /// Narrows the range of rows that this set of ticks represents.
502    ///
503    /// If the range is out of range, this method will panic.
504    pub fn slice(self, range: Range<u32>) -> Self {
505        ContiguousComponentTicksMut {
506            added: &mut self.added[(range.start as usize)..(range.end as usize)],
507            changed: &mut self.changed[(range.start as usize)..(range.end as usize)],
508            summary_tick: self.summary_tick,
509            changed_by: self
510                .changed_by
511                .map(|changed_by| &mut changed_by[(range.start as usize)..(range.end as usize)]),
512            last_run: self.last_run,
513            this_run: self.this_run,
514        }
515    }
516}
517
518impl<'w> From<ContiguousComponentTicksMut<'w>> for ContiguousComponentTicksRef<'w> {
519    fn from(value: ContiguousComponentTicksMut<'w>) -> Self {
520        Self {
521            added: value.added,
522            changed: value.changed,
523            summary_tick: value.summary_tick,
524            changed_by: value.changed_by.map(|v| &*v),
525            last_run: value.last_run,
526            this_run: value.this_run,
527        }
528    }
529}
530
531/// Shared borrow of a [`Resource`].
532///
533/// See the [`Resource`] documentation for usage.
534///
535/// If you need a unique mutable borrow, use [`ResMut`] instead.
536///
537/// This [`SystemParam`](crate::system::SystemParam) fails validation if resource doesn't exist.
538/// This will cause a panic. To skip this system without panicking when the resource
539/// is missing, use [`If<Res<T>>`](crate::system::If).
540///
541/// Use [`Option<Res<T>>`] instead if the resource might not always exist
542/// and you want to handle that case yourself.
543pub struct Res<'w, T: ?Sized + Resource> {
544    pub(crate) value: &'w T,
545    pub(crate) ticks: ComponentTicksRef<'w>,
546}
547
548impl<'w, T: Resource> Res<'w, T> {
549    /// Copies a reference to a resource.
550    ///
551    /// Note that unless you actually need an instance of `Res<T>`, you should
552    /// prefer to just convert it to `&T` which can be freely copied.
553    #[expect(
554        clippy::should_implement_trait,
555        reason = "As this struct derefs to the inner resource, a `Clone` trait implementation would interfere with the common case of cloning the inner content."
556    )]
557    pub fn clone(this: &Self) -> Self {
558        Self {
559            value: this.value,
560            ticks: this.ticks,
561        }
562    }
563
564    /// Due to lifetime limitations of the `Deref` trait, this method can be used to obtain a
565    /// reference of the [`Resource`] with a lifetime bound to `'w` instead of the lifetime of the
566    /// struct itself.
567    pub fn into_inner(self) -> &'w T {
568        self.value
569    }
570}
571
572impl<'w, T: Resource<Mutability = Mutable>> From<ResMut<'w, T>> for Res<'w, T> {
573    fn from(res: ResMut<'w, T>) -> Self {
574        Self {
575            value: res.value,
576            ticks: res.ticks.into(),
577        }
578    }
579}
580
581impl<'w, T: Resource> From<Res<'w, T>> for Ref<'w, T> {
582    /// Convert a `Res` into a `Ref`. This allows keeping the change-detection feature of `Ref`
583    /// while losing the specificity of `Res` for resources.
584    fn from(res: Res<'w, T>) -> Self {
585        Self {
586            value: res.value,
587            ticks: res.ticks,
588        }
589    }
590}
591
592impl<'w, 'a, T: Resource> IntoIterator for &'a Res<'w, T>
593where
594    &'a T: IntoIterator,
595{
596    type Item = <&'a T as IntoIterator>::Item;
597    type IntoIter = <&'a T as IntoIterator>::IntoIter;
598
599    fn into_iter(self) -> Self::IntoIter {
600        self.value.into_iter()
601    }
602}
603change_detection_impl!(Res<'w, T>, T, Resource);
604impl_debug!(Res<'w, T>, Resource);
605
606/// Unique mutable borrow of a [`Resource`].
607///
608/// See the [`Resource`] documentation for usage.
609///
610/// If you need a shared borrow, use [`Res`] instead.
611///
612/// This [`SystemParam`](crate::system::SystemParam) fails validation if resource doesn't exist.
613/// This will cause a panic. To skip this system without panicking when the resource
614/// is missing, use [`If<ResMut<T>>`](crate::system::If).
615///
616/// Use [`Option<ResMut<T>>`] instead if the resource might not always exist
617/// and you want to handle that case yourself.
618pub struct ResMut<'w, T: ?Sized + Resource<Mutability = Mutable>> {
619    pub(crate) value: &'w mut T,
620    pub(crate) ticks: ComponentTicksMut<'w>,
621}
622
623impl<'w, 'a, T: Resource<Mutability = Mutable>> IntoIterator for &'a ResMut<'w, T>
624where
625    &'a T: IntoIterator,
626{
627    type Item = <&'a T as IntoIterator>::Item;
628    type IntoIter = <&'a T as IntoIterator>::IntoIter;
629
630    fn into_iter(self) -> Self::IntoIter {
631        self.value.into_iter()
632    }
633}
634
635impl<'w, 'a, T: Resource<Mutability = Mutable>> IntoIterator for &'a mut ResMut<'w, T>
636where
637    &'a mut T: IntoIterator,
638{
639    type Item = <&'a mut T as IntoIterator>::Item;
640    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
641
642    fn into_iter(self) -> Self::IntoIter {
643        self.set_changed();
644        self.value.into_iter()
645    }
646}
647
648change_detection_impl!(ResMut<'w, T>, T, Resource<Mutability = Mutable>);
649change_detection_mut_impl!(ResMut<'w, T>, T, Resource<Mutability = Mutable>);
650impl_methods!(ResMut<'w, T>, T, Resource<Mutability = Mutable>);
651impl_debug!(ResMut<'w, T>, Resource<Mutability = Mutable>);
652
653impl<'w, T: Resource<Mutability = Mutable>> From<ResMut<'w, T>> for Mut<'w, T> {
654    /// Convert this `ResMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
655    /// while losing the specificity of `ResMut` for resources.
656    fn from(other: ResMut<'w, T>) -> Mut<'w, T> {
657        Mut {
658            value: other.value,
659            ticks: other.ticks,
660        }
661    }
662}
663
664/// Shared borrow of a non-[`Send`] resource.
665///
666/// Only [`Send`] resources may be accessed with the [`Res`] [`SystemParam`](crate::system::SystemParam). In case that the
667/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct
668/// the scheduler to instead run the system on the main thread so that it doesn't send the resource
669/// over to another thread.
670///
671/// This [`SystemParam`](crate::system::SystemParam) fails validation if the non-send resource doesn't exist.
672/// This will cause a panic. To skip this system without panicking when the resource
673/// is missing, use [`If<NonSend<T>>`](crate::system::If).
674///
675/// Use [`Option<NonSend<T>>`] instead if the resource might not always exist
676/// and you want to handle that case yourself.
677pub struct NonSend<'w, T: ?Sized + 'static> {
678    pub(crate) value: &'w T,
679    pub(crate) ticks: ComponentTicksRef<'w>,
680}
681
682change_detection_impl!(NonSend<'w, T>, T,);
683impl_debug!(NonSend<'w, T>,);
684
685impl<'w, T> From<NonSendMut<'w, T>> for NonSend<'w, T> {
686    fn from(other: NonSendMut<'w, T>) -> Self {
687        Self {
688            value: other.value,
689            ticks: other.ticks.into(),
690        }
691    }
692}
693
694/// Unique borrow of a non-[`Send`] resource.
695///
696/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the
697/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct
698/// the scheduler to instead run the system on the main thread so that it doesn't send the resource
699/// over to another thread.
700///
701/// This [`SystemParam`](crate::system::SystemParam) fails validation if non-send resource doesn't exist.
702/// This will cause a panic. To skip this system without panicking when the resource
703/// is missing, use [`If<NonSendMut<T>>`](crate::system::If).
704///
705/// Use [`Option<NonSendMut<T>>`] instead if the resource might not always exist
706/// and you want to handle that case yourself.
707pub struct NonSendMut<'w, T: ?Sized + 'static> {
708    pub(crate) value: &'w mut T,
709    pub(crate) ticks: ComponentTicksMut<'w>,
710}
711
712change_detection_impl!(NonSendMut<'w, T>, T,);
713change_detection_mut_impl!(NonSendMut<'w, T>, T,);
714impl_methods!(NonSendMut<'w, T>, T,);
715impl_debug!(NonSendMut<'w, T>,);
716
717impl<'w, T: 'static> From<NonSendMut<'w, T>> for Mut<'w, T> {
718    /// Convert this `NonSendMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
719    /// while losing the specificity of `NonSendMut`.
720    fn from(other: NonSendMut<'w, T>) -> Mut<'w, T> {
721        Mut {
722            value: other.value,
723            ticks: other.ticks,
724        }
725    }
726}
727
728/// Shared borrow of an entity's component with access to change detection.
729/// Similar to [`Mut`] but is immutable and so doesn't require unique access.
730///
731/// # Examples
732///
733/// These two systems produce the same output.
734///
735/// ```
736/// # use bevy_ecs::change_detection::DetectChanges;
737/// # use bevy_ecs::query::{Changed, With};
738/// # use bevy_ecs::system::Query;
739/// # use bevy_ecs::world::Ref;
740/// # use bevy_ecs_macros::Component;
741/// # #[derive(Component)]
742/// # struct MyComponent;
743///
744/// fn how_many_changed_1(query: Query<(), Changed<MyComponent>>) {
745///     println!("{} changed", query.iter().count());
746/// }
747///
748/// fn how_many_changed_2(query: Query<Ref<MyComponent>>) {
749///     println!("{} changed", query.iter().filter(|c| c.is_changed()).count());
750/// }
751/// ```
752pub struct Ref<'w, T: ?Sized> {
753    pub(crate) value: &'w T,
754    pub(crate) ticks: ComponentTicksRef<'w>,
755}
756
757impl<'w, T: ?Sized> Ref<'w, T> {
758    /// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.
759    pub fn into_inner(self) -> &'w T {
760        self.value
761    }
762
763    /// Map `Ref` to a different type using `f`.
764    ///
765    /// This doesn't do anything else than call `f` on the wrapped value.
766    /// This is equivalent to [`Mut::map_unchanged`].
767    pub fn map<U: ?Sized>(self, f: impl FnOnce(&T) -> &U) -> Ref<'w, U> {
768        Ref {
769            value: f(self.value),
770            ticks: self.ticks,
771        }
772    }
773
774    /// Create a new `Ref` using provided values.
775    ///
776    /// This is an advanced feature, `Ref`s are designed to be _created_ by
777    /// engine-internal code and _consumed_ by end-user code.
778    ///
779    /// - `value` - The value wrapped by `Ref`.
780    /// - `added` - A [`Tick`] that stores the tick when the wrapped value was created.
781    /// - `changed` - A [`Tick`] that stores the last time the wrapped value was changed.
782    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
783    ///   as a reference to determine whether the wrapped value is newly added or changed.
784    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
785    pub fn new(
786        value: &'w T,
787        added: &'w Tick,
788        changed: &'w Tick,
789        last_run: Tick,
790        this_run: Tick,
791        caller: MaybeLocation<&'w &'static Location<'static>>,
792    ) -> Ref<'w, T> {
793        Ref {
794            value,
795            ticks: ComponentTicksRef {
796                added,
797                changed,
798                changed_by: caller,
799                last_run,
800                this_run,
801            },
802        }
803    }
804
805    /// Overwrite the `last_run` and `this_run` tick that are used for change detection.
806    ///
807    /// This is an advanced feature. `Ref`s are usually _created_ by engine-internal code and
808    /// _consumed_ by end-user code.
809    pub fn set_ticks(&mut self, last_run: Tick, this_run: Tick) {
810        self.ticks.last_run = last_run;
811        self.ticks.this_run = this_run;
812    }
813}
814
815// `Ref` is `Copy` to facilitate creation of split borrows. Compared to `Res`
816// (which isn't `Copy`), `Ref` is not as widely used so can afford to require
817// `ref.as_ref().clone()` or `ref.deref().clone()` in order to clone the inner `T`.
818impl<'w, T: ?Sized> Copy for Ref<'w, T> {}
819
820impl<'w, T: ?Sized> Clone for Ref<'w, T> {
821    fn clone(&self) -> Self {
822        *self
823    }
824}
825
826/// Contiguous equivalent of [`Ref<T>`].
827///
828/// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous) for [`Ref<T>`].
829#[derive(Clone)]
830pub struct ContiguousRef<'w, T> {
831    pub(crate) value: &'w [T],
832    pub(crate) ticks: ContiguousComponentTicksRef<'w>,
833}
834
835impl<'w, T> ContiguousRef<'w, T> {
836    /// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.
837    pub fn into_inner(self) -> &'w [T] {
838        self.value
839    }
840
841    /// Returns the added ticks.
842    #[inline]
843    pub fn added_ticks_slice(&self) -> &'w [Tick] {
844        self.ticks.added
845    }
846
847    /// Returns the changed ticks.
848    #[inline]
849    pub fn changed_ticks_slice(&self) -> &'w [Tick] {
850        self.ticks.changed
851    }
852
853    /// Returns the changed by ticks.
854    #[inline]
855    pub fn changed_by_ticks_slice(&self) -> MaybeLocation<&[&'static Location<'static>]> {
856        self.ticks.changed_by.as_deref()
857    }
858
859    /// Returns the tick when the system last ran.
860    #[inline]
861    pub fn last_run_tick(&self) -> Tick {
862        self.ticks.last_run
863    }
864
865    /// Returns the tick of the system's current run.
866    #[inline]
867    pub fn this_run_tick(&self) -> Tick {
868        self.ticks.this_run
869    }
870
871    /// Creates a new `ContiguousRef` using provided values or returns [`None`] if lengths of
872    /// `value`, `added`, `changed` and `changed_by` do not match    
873    ///
874    /// This is an advanced feature, `ContiguousRef`s are designed to be _created_ by
875    /// engine-internal code and _consumed_ by end-user code.
876    ///
877    /// - `value` - The values wrapped by `ContiguousRef`.
878    /// - `added` - [`Tick`]s that store the tick when the wrapped value was created.
879    /// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.
880    /// - `summary_tick` - A [`Tick`] that stores the most recent changed
881    ///   timestamp that was written to any component instance in the column.
882    ///   "Most recent" refers to the wall clock.
883    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
884    ///   as a reference to determine whether the wrapped value is newly added or changed.
885    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
886    /// - `caller` - [`Location`]s that store the location when the wrapper value was changed.
887    pub fn new(
888        value: &'w [T],
889        added: &'w [Tick],
890        changed: &'w [Tick],
891        summary_tick: Option<&'w AtomicTick>,
892        last_run: Tick,
893        this_run: Tick,
894        caller: MaybeLocation<&'w [&'static Location<'static>]>,
895    ) -> Option<Self> {
896        (value.len() == added.len())
897            .then(|| {
898                ContiguousComponentTicksRef::new(
899                    added,
900                    changed,
901                    summary_tick,
902                    last_run,
903                    this_run,
904                    caller,
905                )
906            })
907            .flatten()
908            .map(|ticks| Self { value, ticks })
909    }
910
911    /// Splits [`ContiguousRef`] into it's inner data types.
912    pub fn split(this: Self) -> (&'w [T], ContiguousComponentTicksRef<'w>) {
913        (this.value, this.ticks)
914    }
915
916    /// Reverse of [`ContiguousRef::split`], constructing a [`ContiguousRef`] using components'
917    /// values and ticks.
918    ///
919    /// Returns [`None`] if lengths of `value` and `ticks` do not match, which doesn't happen if
920    /// `ticks` and `value` come from the same [`Self::split`] call.
921    pub fn from_parts(value: &'w [T], ticks: ContiguousComponentTicksRef<'w>) -> Option<Self> {
922        (value.len() == ticks.changed.len()).then_some(Self { value, ticks })
923    }
924
925    /// Narrows the set of rows that this [`ContiguousRef`] represents.
926    ///
927    /// If the given `range` is out of bounds, this method will panic.
928    pub fn slice(self, range: Range<u32>) -> Self {
929        Self {
930            value: &self.value[(range.start as usize)..(range.end as usize)],
931            ticks: self.ticks.slice(range),
932        }
933    }
934}
935
936impl<'w, T> Deref for ContiguousRef<'w, T> {
937    type Target = [T];
938
939    #[inline]
940    fn deref(&self) -> &Self::Target {
941        self.value
942    }
943}
944
945impl<'w, T> AsRef<[T]> for ContiguousRef<'w, T> {
946    #[inline]
947    fn as_ref(&self) -> &[T] {
948        self.deref()
949    }
950}
951
952impl<'w, T> IntoIterator for ContiguousRef<'w, T> {
953    type Item = &'w T;
954
955    type IntoIter = core::slice::Iter<'w, T>;
956
957    fn into_iter(self) -> Self::IntoIter {
958        self.value.iter()
959    }
960}
961
962impl<'w, T: core::fmt::Debug> core::fmt::Debug for ContiguousRef<'w, T> {
963    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
964        f.debug_tuple("ContiguousRef").field(&self.value).finish()
965    }
966}
967
968impl<'w, 'a, T> IntoIterator for &'a Ref<'w, T>
969where
970    &'a T: IntoIterator,
971{
972    type Item = <&'a T as IntoIterator>::Item;
973    type IntoIter = <&'a T as IntoIterator>::IntoIter;
974
975    fn into_iter(self) -> Self::IntoIter {
976        self.value.into_iter()
977    }
978}
979change_detection_impl!(Ref<'w, T>, T,);
980impl_debug!(Ref<'w, T>,);
981
982/// Unique mutable borrow of an entity's component or of a resource.
983///
984/// This can be used in queries to access change detection from immutable query methods, as opposed
985/// to `&mut T` which only provides access to change detection from mutable query methods.
986///
987/// ```rust
988/// # use bevy_ecs::prelude::*;
989/// # use bevy_ecs::query::QueryData;
990/// #
991/// #[derive(Component, Clone, Debug)]
992/// struct Name(String);
993///
994/// #[derive(Component, Clone, Copy, Debug)]
995/// struct Health(f32);
996///
997/// fn my_system(mut query: Query<(Mut<Name>, &mut Health)>) {
998///     // Mutable access provides change detection information for both parameters:
999///     // - `name` has type `Mut<Name>`
1000///     // - `health` has type `Mut<Health>`
1001///     for (name, health) in query.iter_mut() {
1002///         println!("Name: {:?} (last changed {:?})", name, name.last_changed());
1003///         println!("Health: {:?} (last changed: {:?})", health, health.last_changed());
1004/// #        println!("{}{}", name.0, health.0); // Silence dead_code warning
1005///     }
1006///
1007///     // Immutable access only provides change detection for `Name`:
1008///     // - `name` has type `Ref<Name>`
1009///     // - `health` has type `&Health`
1010///     for (name, health) in query.iter() {
1011///         println!("Name: {:?} (last changed {:?})", name, name.last_changed());
1012///         println!("Health: {:?}", health);
1013///     }
1014/// }
1015///
1016/// # bevy_ecs::system::assert_is_system(my_system);
1017/// ```
1018pub struct Mut<'w, T: ?Sized> {
1019    pub(crate) value: &'w mut T,
1020    pub(crate) ticks: ComponentTicksMut<'w>,
1021}
1022
1023impl<'w, T: ?Sized> Mut<'w, T> {
1024    /// Creates a new change-detection enabled smart pointer.
1025    /// In almost all cases you do not need to call this method manually,
1026    /// as instances of `Mut` will be created by engine-internal code.
1027    ///
1028    /// Many use-cases of this method would be better served by [`Mut::map_unchanged`]
1029    /// or [`Mut::reborrow`].
1030    ///
1031    /// - `value` - The value wrapped by this smart pointer.
1032    /// - `added` - A [`Tick`] that stores the tick when the wrapped value was created.
1033    /// - `last_changed` - A [`Tick`] that stores the last time the wrapped value was changed.
1034    ///   This will be updated to the value of `change_tick` if the returned smart pointer
1035    ///   is modified.
1036    /// - `summary_tick` - A [`Tick`] that stores the most recent changed
1037    ///   timestamp that was written to any component instance in the column.
1038    ///   "Most recent" refers to the wall clock.
1039    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
1040    ///   as a reference to determine whether the wrapped value is newly added or changed.
1041    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
1042    pub fn new(
1043        value: &'w mut T,
1044        added: &'w mut Tick,
1045        last_changed: &'w mut Tick,
1046        summary_tick: Option<&'w AtomicTick>,
1047        last_run: Tick,
1048        this_run: Tick,
1049        caller: MaybeLocation<&'w mut &'static Location<'static>>,
1050    ) -> Self {
1051        Self {
1052            value,
1053            ticks: ComponentTicksMut {
1054                added,
1055                changed: last_changed,
1056                changed_by: caller,
1057                last_run,
1058                this_run,
1059                summary_tick,
1060            },
1061        }
1062    }
1063
1064    /// Overwrite the `last_run` and `this_run` tick that are used for change detection.
1065    ///
1066    /// This is an advanced feature. `Mut`s are usually _created_ by engine-internal code and
1067    /// _consumed_ by end-user code.
1068    pub fn set_ticks(&mut self, last_run: Tick, this_run: Tick) {
1069        self.ticks.last_run = last_run;
1070        self.ticks.this_run = this_run;
1071    }
1072}
1073
1074/// Data type returned by [`ContiguousQueryData::fetch_contiguous`](crate::query::ContiguousQueryData::fetch_contiguous)
1075/// for [`Mut<T>`] and `&mut T`
1076///
1077/// # Warning
1078/// Implementations of [`DerefMut`], [`AsMut`] and [`IntoIterator`] update change ticks, which may effect performance.
1079pub struct ContiguousMut<'w, T> {
1080    pub(crate) value: &'w mut [T],
1081    pub(crate) ticks: ContiguousComponentTicksMut<'w>,
1082}
1083
1084impl<'w, T> ContiguousMut<'w, T> {
1085    /// Manually bypasses change detection, allowing you to mutate the underlying values without updating the change tick,
1086    /// which may be useful to reduce amount of work to be done.
1087    ///
1088    /// # Warning
1089    /// This is a risky operation, that can have unexpected consequences on any system relying on this code.
1090    /// However, it can be an essential escape hatch when, for example,
1091    /// you are trying to synchronize representations using change detection and need to avoid infinite recursion.
1092    #[inline]
1093    pub fn bypass_change_detection(&mut self) -> &mut [T] {
1094        self.value
1095    }
1096
1097    /// Returns the immutable added ticks' slice.
1098    #[inline]
1099    pub fn added_ticks_slice(&self) -> &[Tick] {
1100        self.ticks.added
1101    }
1102
1103    /// Returns the immutable changed ticks' slice.
1104    #[inline]
1105    pub fn changed_ticks_slice(&self) -> &[Tick] {
1106        self.ticks.changed
1107    }
1108
1109    /// Returns the mutable changed by ticks' slice
1110    #[inline]
1111    pub fn changed_by_ticks_mut(&self) -> MaybeLocation<&[&'static Location<'static>]> {
1112        self.ticks.changed_by.as_deref()
1113    }
1114
1115    /// Returns the tick when the system last ran.
1116    #[inline]
1117    pub fn last_run_tick(&self) -> Tick {
1118        self.ticks.last_run
1119    }
1120
1121    /// Returns the tick of the system's current run.
1122    #[inline]
1123    pub fn this_run_tick(&self) -> Tick {
1124        self.ticks.this_run
1125    }
1126
1127    /// Returns the mutable added ticks' slice.
1128    #[inline]
1129    pub fn added_ticks_slice_mut(&mut self) -> &mut [Tick] {
1130        self.ticks.added
1131    }
1132
1133    /// Returns the mutable changed ticks' slice.
1134    #[inline]
1135    pub fn changed_ticks_slice_mut(&mut self) -> &mut [Tick] {
1136        self.ticks.changed
1137    }
1138
1139    /// Returns the mutable changed by ticks' slice
1140    #[inline]
1141    pub fn changed_by_ticks_slice_mut(
1142        &mut self,
1143    ) -> MaybeLocation<&mut [&'static Location<'static>]> {
1144        self.ticks.changed_by.as_deref_mut()
1145    }
1146
1147    /// Marks all components as changed.
1148    ///
1149    /// **Runs in O(n), where n is the amount of rows**
1150    #[inline]
1151    pub fn mark_all_as_changed(&mut self) {
1152        self.ticks.mark_all_as_changed();
1153    }
1154
1155    /// Creates a new `ContiguousMut` using provided values or returns [`None`] if lengths of
1156    /// `value`, `added`, `changed` and `changed_by` do not match    
1157    ///
1158    /// This is an advanced feature, `ContiguousMut`s are designed to be _created_ by
1159    /// engine-internal code and _consumed_ by end-user code.
1160    ///
1161    /// - `value` - The values wrapped by `ContiguousMut`.
1162    /// - `added` - [`Tick`]s that store the tick when the wrapped value was created.
1163    /// - `changed` - [`Tick`]s that store the last time the wrapped value was changed.
1164    /// - `summary_tick` - A [`Tick`] that stores the most recent changed
1165    ///   timestamp that was written to any component instance in the column.
1166    ///   "Most recent" refers to the wall clock.
1167    /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used
1168    ///   as a reference to determine whether the wrapped value is newly added or changed.
1169    /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now".
1170    /// - `caller` - [`Location`]s that store the location when the wrapper value was changed.
1171    pub fn new(
1172        value: &'w mut [T],
1173        added: &'w mut [Tick],
1174        changed: &'w mut [Tick],
1175        summary_tick: Option<&'w AtomicTick>,
1176        last_run: Tick,
1177        this_run: Tick,
1178        caller: MaybeLocation<&'w mut [&'static Location<'static>]>,
1179    ) -> Option<Self> {
1180        (value.len() == added.len())
1181            .then(|| {
1182                ContiguousComponentTicksMut::new(
1183                    added,
1184                    changed,
1185                    summary_tick,
1186                    last_run,
1187                    this_run,
1188                    caller,
1189                )
1190            })
1191            .flatten()
1192            .map(|ticks| Self { value, ticks })
1193    }
1194
1195    /// Returns a `ContiguousMut<T>` with a smaller lifetime.
1196    pub fn reborrow(&mut self) -> ContiguousMut<'_, T> {
1197        ContiguousMut {
1198            value: self.value,
1199            ticks: self.ticks.reborrow(),
1200        }
1201    }
1202
1203    /// Splits [`ContiguousMut`] into it's inner data types. It may be useful, when you want to
1204    /// have an iterator over component values and check ticks simultaneously (using
1205    /// [`ContiguousComponentTicksMut::is_changed_iter`] and
1206    /// [`ContiguousComponentTicksMut::is_added_iter`]).
1207    ///
1208    /// Variant of [`Self::split`] which bypasses change detection: [`Self::bypass_change_detection_split`].
1209    ///
1210    /// Reverse of [`Self::split`] is [`Self::from_parts`].
1211    ///
1212    /// # Warning
1213    /// This version updates changed ticks **before** returning, hence
1214    /// [`ContiguousComponentTicksMut::is_changed_iter`] will be useless (the iterator will be filled with
1215    /// [`prim@true`]s).
1216    // NOTE: `ticks_since_insert` will be 0 (because `this.mark_all_as_changed` makes all changed ticks `this_run`),
1217    // `ticks_since_system` won't be 0, `tick` is newer if
1218    // `ticks_since_system` > `ticks_since_insert`, hence it will always be true.
1219    pub fn split(mut this: Self) -> (&'w mut [T], ContiguousComponentTicksMut<'w>) {
1220        this.mark_all_as_changed();
1221        (this.value, this.ticks)
1222    }
1223
1224    /// Splits [`ContiguousMut`] into it's inner data types. It may be useful, when you want to
1225    /// have an iterator over component values and check ticks simultaneously (using
1226    /// [`ContiguousComponentTicksMut::is_changed_iter`] and
1227    /// [`ContiguousComponentTicksMut::is_added_iter`]).
1228    ///
1229    /// Variant of [`Self::bypass_change_detection_split`] which **does not** bypass change detection: [`Self::split`].
1230    ///
1231    /// Reverse of [`Self::bypass_change_detection_split`] is [`Self::from_parts`].
1232    ///
1233    /// # Warning
1234    /// **Bypasses change detection**, call [`Self::split`] if you don't want to bypass it.
1235    ///
1236    /// See [`Self::bypass_change_detection`] for further explanations.
1237    pub fn bypass_change_detection_split(
1238        this: Self,
1239    ) -> (&'w mut [T], ContiguousComponentTicksMut<'w>) {
1240        (this.value, this.ticks)
1241    }
1242
1243    /// Reverse of [`ContiguousMut::split`] and [`ContiguousMut::bypass_change_detection_split`],
1244    /// constructing a [`ContiguousMut`] using components' values and ticks.
1245    ///
1246    /// Returns [`None`] if lengths of `value` and `ticks` do not match, which doesn't happen if
1247    /// `ticks` and `value` come from the same [`Self::split`] or [`Self::bypass_change_detection_split`] call.
1248    pub fn from_parts(value: &'w mut [T], ticks: ContiguousComponentTicksMut<'w>) -> Option<Self> {
1249        (value.len() == ticks.changed.len()).then_some(Self { value, ticks })
1250    }
1251
1252    /// Narrows the range of rows that this [`ContiguousMut`] represents.
1253    ///
1254    /// If the given `range` is out of bounds, this method will panic.
1255    pub fn slice(self, range: Range<u32>) -> Self {
1256        Self {
1257            value: &mut self.value[(range.start as usize)..(range.end as usize)],
1258            ticks: self.ticks.slice(range),
1259        }
1260    }
1261}
1262
1263impl<'w, T> Deref for ContiguousMut<'w, T> {
1264    type Target = [T];
1265
1266    #[inline]
1267    fn deref(&self) -> &Self::Target {
1268        self.value
1269    }
1270}
1271
1272impl<'w, T> DerefMut for ContiguousMut<'w, T> {
1273    #[inline]
1274    fn deref_mut(&mut self) -> &mut Self::Target {
1275        self.mark_all_as_changed();
1276        self.value
1277    }
1278}
1279
1280impl<'w, T> AsRef<[T]> for ContiguousMut<'w, T> {
1281    #[inline]
1282    fn as_ref(&self) -> &[T] {
1283        self.deref()
1284    }
1285}
1286
1287impl<'w, T> AsMut<[T]> for ContiguousMut<'w, T> {
1288    #[inline]
1289    fn as_mut(&mut self) -> &mut [T] {
1290        self.deref_mut()
1291    }
1292}
1293
1294impl<'w, T> IntoIterator for ContiguousMut<'w, T> {
1295    type Item = &'w mut T;
1296
1297    type IntoIter = core::slice::IterMut<'w, T>;
1298
1299    fn into_iter(mut self) -> Self::IntoIter {
1300        self.mark_all_as_changed();
1301        self.value.iter_mut()
1302    }
1303}
1304
1305impl<'w, T: core::fmt::Debug> core::fmt::Debug for ContiguousMut<'w, T> {
1306    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1307        f.debug_tuple("ContiguousMut").field(&self.value).finish()
1308    }
1309}
1310
1311impl<'w, T> From<ContiguousMut<'w, T>> for ContiguousRef<'w, T> {
1312    fn from(value: ContiguousMut<'w, T>) -> Self {
1313        Self {
1314            value: value.value,
1315            ticks: value.ticks.into(),
1316        }
1317    }
1318}
1319
1320impl<'w, T: ?Sized> From<Mut<'w, T>> for Ref<'w, T> {
1321    fn from(mut_ref: Mut<'w, T>) -> Self {
1322        Self {
1323            value: mut_ref.value,
1324            ticks: mut_ref.ticks.into(),
1325        }
1326    }
1327}
1328
1329impl<'w, 'a, T> IntoIterator for &'a Mut<'w, T>
1330where
1331    &'a T: IntoIterator,
1332{
1333    type Item = <&'a T as IntoIterator>::Item;
1334    type IntoIter = <&'a T as IntoIterator>::IntoIter;
1335
1336    fn into_iter(self) -> Self::IntoIter {
1337        self.value.into_iter()
1338    }
1339}
1340
1341impl<'w, 'a, T> IntoIterator for &'a mut Mut<'w, T>
1342where
1343    &'a mut T: IntoIterator,
1344{
1345    type Item = <&'a mut T as IntoIterator>::Item;
1346    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
1347
1348    fn into_iter(self) -> Self::IntoIter {
1349        self.set_changed();
1350        self.value.into_iter()
1351    }
1352}
1353
1354change_detection_impl!(Mut<'w, T>, T,);
1355change_detection_mut_impl!(Mut<'w, T>, T,);
1356impl_methods!(Mut<'w, T>, T,);
1357impl_debug!(Mut<'w, T>,);
1358
1359/// Unique mutable borrow of resources or an entity's component.
1360///
1361/// Similar to [`Mut`], but not generic over the component type, instead
1362/// exposing the raw pointer as a `*mut ()`.
1363///
1364/// Usually you don't need to use this and can instead use the APIs returning a
1365/// [`Mut`], but in situations where the types are not known at compile time
1366/// or are defined outside of rust this can be used.
1367pub struct MutUntyped<'w> {
1368    pub(crate) value: PtrMut<'w>,
1369    pub(crate) ticks: ComponentTicksMut<'w>,
1370}
1371
1372impl<'w> MutUntyped<'w> {
1373    /// Returns the pointer to the value, marking it as changed.
1374    ///
1375    /// In order to avoid marking the value as changed, you need to call [`bypass_change_detection`](DetectChangesMut::bypass_change_detection).
1376    #[inline]
1377    pub fn into_inner(mut self) -> PtrMut<'w> {
1378        self.set_changed();
1379        self.value
1380    }
1381
1382    /// Returns a [`MutUntyped`] with a smaller lifetime.
1383    /// This is useful if you have `&mut MutUntyped`, but you need a `MutUntyped`.
1384    #[inline]
1385    pub fn reborrow(&mut self) -> MutUntyped<'_> {
1386        MutUntyped {
1387            value: self.value.reborrow(),
1388            ticks: ComponentTicksMut {
1389                added: self.ticks.added,
1390                changed: self.ticks.changed,
1391                changed_by: self.ticks.changed_by.as_deref_mut(),
1392                last_run: self.ticks.last_run,
1393                this_run: self.ticks.this_run,
1394                summary_tick: self.ticks.summary_tick,
1395            },
1396        }
1397    }
1398
1399    /// Returns `true` if this value was changed or mutably dereferenced
1400    /// either since a specific change tick.
1401    pub fn has_changed_since(&self, tick: Tick) -> bool {
1402        self.ticks.changed.is_newer_than(tick, self.ticks.this_run)
1403    }
1404
1405    /// Returns a pointer to the value without taking ownership of this smart pointer, marking it as changed.
1406    ///
1407    /// In order to avoid marking the value as changed, you need to call [`bypass_change_detection`](DetectChangesMut::bypass_change_detection).
1408    #[inline]
1409    pub fn as_mut(&mut self) -> PtrMut<'_> {
1410        self.set_changed();
1411        self.value.reborrow()
1412    }
1413
1414    /// Returns an immutable pointer to the value without taking ownership.
1415    #[inline]
1416    pub fn as_ref(&self) -> Ptr<'_> {
1417        self.value.as_ref()
1418    }
1419
1420    /// Turn this [`MutUntyped`] into a [`Mut`] by mapping the inner [`PtrMut`] to another value,
1421    /// without flagging a change.
1422    /// This function is the untyped equivalent of [`Mut::map_unchanged`].
1423    ///
1424    /// 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.
1425    ///
1426    /// If you know the type of the value you can do
1427    /// ```no_run
1428    /// # use bevy_ecs::change_detection::{Mut, MutUntyped};
1429    /// # let mut_untyped: MutUntyped = unimplemented!();
1430    /// // SAFETY: ptr is of type `u8`
1431    /// mut_untyped.map_unchanged(|ptr| unsafe { ptr.deref_mut::<u8>() });
1432    /// ```
1433    /// If you have a [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr) that you know belongs to this [`MutUntyped`],
1434    /// you can do
1435    /// ```no_run
1436    /// # use bevy_ecs::change_detection::{Mut, MutUntyped};
1437    /// # let mut_untyped: MutUntyped = unimplemented!();
1438    /// # let reflect_from_ptr: bevy_reflect::ReflectFromPtr = unimplemented!();
1439    /// // SAFETY: from the context it is known that `ReflectFromPtr` was made for the type of the `MutUntyped`
1440    /// mut_untyped.map_unchanged(|ptr| unsafe { reflect_from_ptr.ptr_as_reflect_mut(ptr) });
1441    /// ```
1442    pub fn map_unchanged<T: ?Sized>(self, f: impl FnOnce(PtrMut<'w>) -> &'w mut T) -> Mut<'w, T> {
1443        Mut {
1444            value: f(self.value),
1445            ticks: self.ticks,
1446        }
1447    }
1448
1449    /// Transforms this [`MutUntyped`] into a [`Mut<T>`] with the same lifetime.
1450    ///
1451    /// # Safety
1452    /// - `T` must be the erased pointee type for this [`MutUntyped`].
1453    pub unsafe fn with_type<T>(self) -> Mut<'w, T> {
1454        Mut {
1455            // SAFETY: `value` is `Aligned` and caller ensures the pointee type is `T`.
1456            value: unsafe { self.value.deref_mut() },
1457            ticks: self.ticks,
1458        }
1459    }
1460}
1461
1462impl<'w> DetectChanges for MutUntyped<'w> {
1463    #[inline]
1464    fn is_added(&self) -> bool {
1465        self.is_added_after(self.ticks.last_run)
1466    }
1467
1468    #[inline]
1469    fn is_changed(&self) -> bool {
1470        self.is_changed_after(self.ticks.last_run)
1471    }
1472
1473    #[inline]
1474    fn is_added_after(&self, other: Tick) -> bool {
1475        self.ticks.added.is_newer_than(other, self.ticks.this_run)
1476    }
1477
1478    #[inline]
1479    fn is_changed_after(&self, other: Tick) -> bool {
1480        self.ticks.changed.is_newer_than(other, self.ticks.this_run)
1481    }
1482
1483    #[inline]
1484    fn last_changed(&self) -> Tick {
1485        *self.ticks.changed
1486    }
1487
1488    #[inline]
1489    fn changed_by(&self) -> MaybeLocation {
1490        self.ticks.changed_by.copied()
1491    }
1492
1493    #[inline]
1494    fn added(&self) -> Tick {
1495        *self.ticks.added
1496    }
1497
1498    #[inline]
1499    fn this_run(&self) -> Tick {
1500        self.ticks.this_run
1501    }
1502
1503    #[inline]
1504    fn last_run(&self) -> Tick {
1505        self.ticks.last_run
1506    }
1507}
1508
1509impl<'w> DetectChangesMut for MutUntyped<'w> {
1510    type Inner = PtrMut<'w>;
1511
1512    #[inline]
1513    #[track_caller]
1514    fn set_changed(&mut self) {
1515        *self.ticks.changed = self.ticks.this_run;
1516        self.ticks.changed_by.assign(MaybeLocation::caller());
1517    }
1518
1519    #[inline]
1520    #[track_caller]
1521    fn set_added(&mut self) {
1522        *self.ticks.changed = self.ticks.this_run;
1523        *self.ticks.added = self.ticks.this_run;
1524        self.ticks.changed_by.assign(MaybeLocation::caller());
1525    }
1526
1527    #[inline]
1528    #[track_caller]
1529    fn set_last_changed(&mut self, last_changed: Tick) {
1530        *self.ticks.changed = last_changed;
1531        self.ticks.changed_by.assign(MaybeLocation::caller());
1532    }
1533
1534    #[inline]
1535    #[track_caller]
1536    fn set_last_added(&mut self, last_added: Tick) {
1537        *self.ticks.added = last_added;
1538        *self.ticks.changed = last_added;
1539        self.ticks.changed_by.assign(MaybeLocation::caller());
1540    }
1541
1542    #[inline]
1543    #[track_caller]
1544    fn bypass_change_detection(&mut self) -> &mut Self::Inner {
1545        &mut self.value
1546    }
1547}
1548
1549impl core::fmt::Debug for MutUntyped<'_> {
1550    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1551        f.debug_tuple("MutUntyped")
1552            .field(&self.value.as_ptr())
1553            .finish()
1554    }
1555}
1556
1557impl<'w, T> From<Mut<'w, T>> for MutUntyped<'w> {
1558    fn from(value: Mut<'w, T>) -> Self {
1559        MutUntyped {
1560            value: value.value.into(),
1561            ticks: value.ticks,
1562        }
1563    }
1564}