diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 1bf6a22d18..09efcf5c91 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -542,6 +542,46 @@ impl<'a, T: ?Sized> Ref<'a, T> { pub fn into_inner(self) -> &'a T { self.value } + + /// Map `Ref` to a different type using `f`. + /// + /// This doesn't do anything else than call `f` on the wrapped value. + /// This is equivalent to [`Mut::map_unchanged`]. + pub fn map(self, f: impl FnOnce(&T) -> &U) -> Ref<'a, U> { + Ref { + value: f(self.value), + ticks: self.ticks, + } + } + + /// Create a new `Ref` using provided values. + /// + /// This is an advanced feature, `Ref`s are designed to be _created_ by + /// engine-internal code and _consumed_ by end-user code. + /// + /// - `value` - The value wrapped by `Ref`. + /// - `added` - A [`Tick`] that stores the tick when the wrapped value was created. + /// - `changed` - A [`Tick`] that stores the last time the wrapped value was changed. + /// - `last_run` - A [`Tick`], occurring before `this_run`, which is used + /// as a reference to determine whether the wrapped value is newly added or changed. + /// - `this_run` - A [`Tick`] corresponding to the current point in time -- "now". + pub fn new( + value: &'a T, + added: &'a Tick, + changed: &'a Tick, + last_run: Tick, + this_run: Tick, + ) -> Ref<'a, T> { + Ref { + value, + ticks: Ticks { + added, + changed, + last_run, + this_run, + }, + } + } } impl<'w, 'a, T> IntoIterator for &'a Ref<'w, T>