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},
|
||||
schedule::{Schedule, Stage, SystemStage},
|
||||
system::{
|
||||
ConfigurableSystem, IntoExclusiveSystem, IntoSystem, Local, Query, QuerySet,
|
||||
RemovedComponents, Res, ResMut, System, SystemState,
|
||||
ConfigurableSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, Query,
|
||||
QuerySet, RemovedComponents, Res, ResMut, System, SystemState,
|
||||
},
|
||||
world::{FromWorld, World},
|
||||
};
|
||||
@ -331,6 +331,48 @@ mod tests {
|
||||
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]
|
||||
fn remove_tracking() {
|
||||
let mut world = World::new();
|
||||
|
||||
@ -820,7 +820,7 @@ impl<'w, 's, T: 'static> SystemParamFetch<'w, 's> for NonSendState<T> {
|
||||
/// See: [`NonSend<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>;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
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();
|
||||
if combined_access.has_write(component_id) {
|
||||
panic!(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user