Implement SystemParam::queue()
method for blanket implementation of ParamSet
(#15599)
# Objective The `queue()` method is an optional trait method which is necessary for deferred operations (such as command queues) to work properly in the context of an observer. This method was omitted from the proc_macro blanket implementation of `ParamSet` for tuples; as a result, SystemParams with deferred application (such as Commands) would not work in observers if they were part of a ParamSet. This appears to have been a simple omission, as `queue()` was already implemented for the separate blanket implementation of `ParamSet` for `Vec<T>`. In both cases, it is a simple pass-through to the component SystemParams. ## Solution Add the `queue()` method implementation to the `impl_param_set` proco macro. ## Testing Added a unit test which clearly demonstrates the issue. It fails before the fix, and passes afterwards. ---
This commit is contained in:
parent
587a508ef9
commit
8fb55dbf59
@ -376,6 +376,10 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
|
||||
<(#(#param,)*) as SystemParam>::apply(state, system_meta, world);
|
||||
}
|
||||
|
||||
fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
|
||||
<(#(#param,)*) as SystemParam>::queue(state, system_meta, world.reborrow());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn validate_param<'w, 's>(
|
||||
state: &'s Self::State,
|
||||
|
@ -1211,4 +1211,27 @@ mod tests {
|
||||
|
||||
assert!(world.get_resource::<ResB>().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn observer_apply_deferred_from_param_set() {
|
||||
#[derive(Event)]
|
||||
struct EventA;
|
||||
|
||||
#[derive(Resource)]
|
||||
struct ResA;
|
||||
|
||||
let mut world = World::new();
|
||||
world.observe(
|
||||
|_: Trigger<EventA>, mut params: ParamSet<(Query<Entity>, Commands)>| {
|
||||
params.p1().insert_resource(ResA);
|
||||
},
|
||||
);
|
||||
// TODO: ideally this flush is not necessary, but right now observe() returns WorldEntityMut
|
||||
// and therefore does not automatically flush.
|
||||
world.flush();
|
||||
world.trigger(EventA);
|
||||
world.flush();
|
||||
|
||||
assert!(world.get_resource::<ResA>().is_some());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user