Fix Option<NonSend<T>> and Option<NonSendMut<T>> (#2757)
# Objective Fix `Option<NonSend<T>>` to work when T isn't `Send` Fix `Option<NonSendMut<T>>` to work when T isnt in the world. ## Solution Simple two row fix, properly initialize T in `OptionNonSendState` and remove `T: Component` bound for `Option<NonSendMut<T>>` also added a rudimentary test Co-authored-by: Ïvar Källström <ivar.kallstrom@gmail.com>
This commit is contained in:
parent
c563dd094f
commit
35979922df
@ -27,8 +27,8 @@ mod tests {
|
|||||||
query::{Added, Changed, Or, QueryState, With, Without},
|
query::{Added, Changed, Or, QueryState, With, Without},
|
||||||
schedule::{Schedule, Stage, SystemStage},
|
schedule::{Schedule, Stage, SystemStage},
|
||||||
system::{
|
system::{
|
||||||
ConfigurableSystem, IntoExclusiveSystem, IntoSystem, Local, Query, QuerySet,
|
ConfigurableSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, Query,
|
||||||
RemovedComponents, Res, ResMut, System, SystemState,
|
QuerySet, RemovedComponents, Res, ResMut, System, SystemState,
|
||||||
},
|
},
|
||||||
world::{FromWorld, World},
|
world::{FromWorld, World},
|
||||||
};
|
};
|
||||||
@ -331,6 +331,48 @@ mod tests {
|
|||||||
assert!(*world.get_resource::<bool>().unwrap());
|
assert!(*world.get_resource::<bool>().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_send_option_system() {
|
||||||
|
let mut world = World::default();
|
||||||
|
|
||||||
|
world.insert_resource(false);
|
||||||
|
struct NotSend1(std::rc::Rc<i32>);
|
||||||
|
struct NotSend2(std::rc::Rc<i32>);
|
||||||
|
world.insert_non_send(NotSend1(std::rc::Rc::new(0)));
|
||||||
|
|
||||||
|
fn sys(
|
||||||
|
op: Option<NonSend<NotSend1>>,
|
||||||
|
mut _op2: Option<NonSendMut<NotSend2>>,
|
||||||
|
mut run: ResMut<bool>,
|
||||||
|
) {
|
||||||
|
op.expect("NonSend should exist");
|
||||||
|
*run = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
run_system(&mut world, sys);
|
||||||
|
// ensure the system actually ran
|
||||||
|
assert!(*world.get_resource::<bool>().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_send_system() {
|
||||||
|
let mut world = World::default();
|
||||||
|
|
||||||
|
world.insert_resource(false);
|
||||||
|
struct NotSend1(std::rc::Rc<i32>);
|
||||||
|
struct NotSend2(std::rc::Rc<i32>);
|
||||||
|
|
||||||
|
world.insert_non_send(NotSend1(std::rc::Rc::new(1)));
|
||||||
|
world.insert_non_send(NotSend2(std::rc::Rc::new(2)));
|
||||||
|
|
||||||
|
fn sys(_op: NonSend<NotSend1>, mut _op2: NonSendMut<NotSend2>, mut run: ResMut<bool>) {
|
||||||
|
*run = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
run_system(&mut world, sys);
|
||||||
|
assert!(*world.get_resource::<bool>().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remove_tracking() {
|
fn remove_tracking() {
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
|
|||||||
@ -820,7 +820,7 @@ impl<'w, 's, T: 'static> SystemParamFetch<'w, 's> for NonSendState<T> {
|
|||||||
/// See: [`NonSend<T>`]
|
/// See: [`NonSend<T>`]
|
||||||
pub struct OptionNonSendState<T>(NonSendState<T>);
|
pub struct OptionNonSendState<T>(NonSendState<T>);
|
||||||
|
|
||||||
impl<'w, T: Component> SystemParam for Option<NonSend<'w, T>> {
|
impl<'w, T: 'static> SystemParam for Option<NonSend<'w, T>> {
|
||||||
type Fetch = OptionNonSendState<T>;
|
type Fetch = OptionNonSendState<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,7 +877,7 @@ unsafe impl<T: 'static> SystemParamState for NonSendMutState<T> {
|
|||||||
fn init(world: &mut World, system_meta: &mut SystemMeta, _config: Self::Config) -> Self {
|
fn init(world: &mut World, system_meta: &mut SystemMeta, _config: Self::Config) -> Self {
|
||||||
system_meta.set_non_send();
|
system_meta.set_non_send();
|
||||||
|
|
||||||
let component_id = world.components.get_or_insert_non_send_resource_id::<T>();
|
let component_id = world.initialize_non_send_resource::<T>();
|
||||||
let combined_access = system_meta.component_access_set.combined_access_mut();
|
let combined_access = system_meta.component_access_set.combined_access_mut();
|
||||||
if combined_access.has_write(component_id) {
|
if combined_access.has_write(component_id) {
|
||||||
panic!(
|
panic!(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user