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}