mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
Conversion of ResMut
and NonSendMut
to Mut
(#5438)
# Objective Enable treating components and resources equally, which can simplify the implementation of some systems where only the change detection feature is relevant and not the kind of object (resource or component). ## Solution Implement `From<ResMut<T>>` and `From<NonSendMut<T>>` for `Mut`. Since the 3 structs are similar, and only differ by their system param role, the conversion is trivial. --- ## Changelog Added - `From<ResMut>` and `From<NonSendMut>` for `Mut<T>`.
This commit is contained in:
parent
231894a3a6
commit
d4787111a3
1 changed files with 75 additions and 1 deletions
|
@ -185,6 +185,17 @@ change_detection_impl!(ResMut<'a, T>, T, Resource);
|
||||||
impl_into_inner!(ResMut<'a, T>, T, Resource);
|
impl_into_inner!(ResMut<'a, T>, T, Resource);
|
||||||
impl_debug!(ResMut<'a, T>, Resource);
|
impl_debug!(ResMut<'a, T>, Resource);
|
||||||
|
|
||||||
|
impl<'a, T: Resource> From<ResMut<'a, T>> for Mut<'a, T> {
|
||||||
|
/// Convert this `ResMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
|
||||||
|
/// while losing the specificity of `ResMut` for resources.
|
||||||
|
fn from(other: ResMut<'a, T>) -> Mut<'a, T> {
|
||||||
|
Mut {
|
||||||
|
value: other.value,
|
||||||
|
ticks: other.ticks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unique borrow of a non-[`Send`] resource.
|
/// Unique borrow of a non-[`Send`] resource.
|
||||||
///
|
///
|
||||||
/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the
|
/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the
|
||||||
|
@ -206,6 +217,17 @@ change_detection_impl!(NonSendMut<'a, T>, T,);
|
||||||
impl_into_inner!(NonSendMut<'a, T>, T,);
|
impl_into_inner!(NonSendMut<'a, T>, T,);
|
||||||
impl_debug!(NonSendMut<'a, T>,);
|
impl_debug!(NonSendMut<'a, T>,);
|
||||||
|
|
||||||
|
impl<'a, T: Resource> From<NonSendMut<'a, T>> for Mut<'a, T> {
|
||||||
|
/// Convert this `NonSendMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
|
||||||
|
/// while losing the specificity of `NonSendMut`.
|
||||||
|
fn from(other: NonSendMut<'a, T>) -> Mut<'a, T> {
|
||||||
|
Mut {
|
||||||
|
value: other.value,
|
||||||
|
ticks: other.ticks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unique mutable borrow of an entity's component
|
/// Unique mutable borrow of an entity's component
|
||||||
pub struct Mut<'a, T> {
|
pub struct Mut<'a, T> {
|
||||||
pub(crate) value: &'a mut T,
|
pub(crate) value: &'a mut T,
|
||||||
|
@ -286,7 +308,9 @@ impl std::fmt::Debug for MutUntyped<'_> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
self as bevy_ecs,
|
self as bevy_ecs,
|
||||||
change_detection::{CHECK_TICK_THRESHOLD, MAX_CHANGE_AGE},
|
change_detection::{
|
||||||
|
ComponentTicks, Mut, NonSendMut, ResMut, Ticks, CHECK_TICK_THRESHOLD, MAX_CHANGE_AGE,
|
||||||
|
},
|
||||||
component::Component,
|
component::Component,
|
||||||
query::ChangeTrackers,
|
query::ChangeTrackers,
|
||||||
system::{IntoSystem, Query, System},
|
system::{IntoSystem, Query, System},
|
||||||
|
@ -296,6 +320,8 @@ mod tests {
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct C;
|
struct C;
|
||||||
|
|
||||||
|
struct R; // Resource
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn change_expiration() {
|
fn change_expiration() {
|
||||||
fn change_detected(query: Query<ChangeTrackers<C>>) -> bool {
|
fn change_detected(query: Query<ChangeTrackers<C>>) -> bool {
|
||||||
|
@ -382,4 +408,52 @@ mod tests {
|
||||||
assert!(ticks_since_change == MAX_CHANGE_AGE);
|
assert!(ticks_since_change == MAX_CHANGE_AGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mut_from_res_mut() {
|
||||||
|
let mut component_ticks = ComponentTicks {
|
||||||
|
added: 1,
|
||||||
|
changed: 2,
|
||||||
|
};
|
||||||
|
let ticks = Ticks {
|
||||||
|
component_ticks: &mut component_ticks,
|
||||||
|
last_change_tick: 3,
|
||||||
|
change_tick: 4,
|
||||||
|
};
|
||||||
|
let mut res = R {};
|
||||||
|
let res_mut = ResMut {
|
||||||
|
value: &mut res,
|
||||||
|
ticks,
|
||||||
|
};
|
||||||
|
|
||||||
|
let into_mut: Mut<R> = res_mut.into();
|
||||||
|
assert_eq!(1, into_mut.ticks.component_ticks.added);
|
||||||
|
assert_eq!(2, into_mut.ticks.component_ticks.changed);
|
||||||
|
assert_eq!(3, into_mut.ticks.last_change_tick);
|
||||||
|
assert_eq!(4, into_mut.ticks.change_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mut_from_non_send_mut() {
|
||||||
|
let mut component_ticks = ComponentTicks {
|
||||||
|
added: 1,
|
||||||
|
changed: 2,
|
||||||
|
};
|
||||||
|
let ticks = Ticks {
|
||||||
|
component_ticks: &mut component_ticks,
|
||||||
|
last_change_tick: 3,
|
||||||
|
change_tick: 4,
|
||||||
|
};
|
||||||
|
let mut res = R {};
|
||||||
|
let non_send_mut = NonSendMut {
|
||||||
|
value: &mut res,
|
||||||
|
ticks,
|
||||||
|
};
|
||||||
|
|
||||||
|
let into_mut: Mut<R> = non_send_mut.into();
|
||||||
|
assert_eq!(1, into_mut.ticks.component_ticks.added);
|
||||||
|
assert_eq!(2, into_mut.ticks.component_ticks.changed);
|
||||||
|
assert_eq!(3, into_mut.ticks.last_change_tick);
|
||||||
|
assert_eq!(4, into_mut.ticks.change_tick);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue