Support fallible one-shot systems (#19678)
Closes #19677. I don't think that the output type needs to be `Send`. I've done some test at it seems to work fine without it, which in IMO makes sense, but please correct me if that is not the case.
This commit is contained in:
parent
2915a3b903
commit
d1c6fbea57
@ -144,10 +144,11 @@ where
|
||||
|
||||
/// A [`Command`] that runs the given system,
|
||||
/// caching its [`SystemId`] in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
|
||||
pub fn run_system_cached<M, S>(system: S) -> impl Command<Result>
|
||||
pub fn run_system_cached<O, M, S>(system: S) -> impl Command<Result>
|
||||
where
|
||||
O: 'static,
|
||||
M: 'static,
|
||||
S: IntoSystem<(), (), M> + Send + 'static,
|
||||
S: IntoSystem<(), O, M> + Send + 'static,
|
||||
{
|
||||
move |world: &mut World| -> Result {
|
||||
world.run_system_cached(system)?;
|
||||
@ -157,11 +158,15 @@ where
|
||||
|
||||
/// A [`Command`] that runs the given system with the given input value,
|
||||
/// caching its [`SystemId`] in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
|
||||
pub fn run_system_cached_with<I, M, S>(system: S, input: I::Inner<'static>) -> impl Command<Result>
|
||||
pub fn run_system_cached_with<I, O, M, S>(
|
||||
system: S,
|
||||
input: I::Inner<'static>,
|
||||
) -> impl Command<Result>
|
||||
where
|
||||
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
||||
O: 'static,
|
||||
M: 'static,
|
||||
S: IntoSystem<I, (), M> + Send + 'static,
|
||||
S: IntoSystem<I, O, M> + Send + 'static,
|
||||
{
|
||||
move |world: &mut World| -> Result {
|
||||
world.run_system_cached_with(system, input)?;
|
||||
@ -175,7 +180,7 @@ where
|
||||
pub fn unregister_system<I, O>(system_id: SystemId<I, O>) -> impl Command<Result>
|
||||
where
|
||||
I: SystemInput + Send + 'static,
|
||||
O: Send + 'static,
|
||||
O: 'static,
|
||||
{
|
||||
move |world: &mut World| -> Result {
|
||||
world.unregister_system(system_id)?;
|
||||
|
@ -872,7 +872,7 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
///
|
||||
/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
|
||||
/// which will be handled by [logging the error at the `warn` level](warn).
|
||||
pub fn run_system(&mut self, id: SystemId) {
|
||||
pub fn run_system<O: 'static>(&mut self, id: SystemId<(), O>) {
|
||||
self.queue(command::run_system(id).handle_error_with(warn));
|
||||
}
|
||||
|
||||
@ -965,7 +965,7 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
) -> SystemId<I, O>
|
||||
where
|
||||
I: SystemInput + Send + 'static,
|
||||
O: Send + 'static,
|
||||
O: 'static,
|
||||
{
|
||||
let entity = self.spawn_empty().id();
|
||||
let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));
|
||||
@ -990,7 +990,7 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
|
||||
where
|
||||
I: SystemInput + Send + 'static,
|
||||
O: Send + 'static,
|
||||
O: 'static,
|
||||
{
|
||||
self.queue(command::unregister_system(system_id).handle_error_with(warn));
|
||||
}
|
||||
@ -1039,10 +1039,11 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
/// consider passing them in as inputs via [`Commands::run_system_cached_with`].
|
||||
///
|
||||
/// If that's not an option, consider [`Commands::register_system`] instead.
|
||||
pub fn run_system_cached<M, S>(&mut self, system: S)
|
||||
pub fn run_system_cached<O, M, S>(&mut self, system: S)
|
||||
where
|
||||
O: 'static,
|
||||
M: 'static,
|
||||
S: IntoSystem<(), (), M> + Send + 'static,
|
||||
S: IntoSystem<(), O, M> + Send + 'static,
|
||||
{
|
||||
self.queue(command::run_system_cached(system).handle_error_with(warn));
|
||||
}
|
||||
@ -1069,11 +1070,12 @@ impl<'w, 's> Commands<'w, 's> {
|
||||
/// consider passing them in as inputs.
|
||||
///
|
||||
/// If that's not an option, consider [`Commands::register_system`] instead.
|
||||
pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)
|
||||
pub fn run_system_cached_with<I, O, M, S>(&mut self, system: S, input: I::Inner<'static>)
|
||||
where
|
||||
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
||||
O: 'static,
|
||||
M: 'static,
|
||||
S: IntoSystem<I, (), M> + Send + 'static,
|
||||
S: IntoSystem<I, O, M> + Send + 'static,
|
||||
{
|
||||
self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));
|
||||
}
|
||||
|
@ -651,6 +651,19 @@ mod tests {
|
||||
assert_eq!(output, NonCopy(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fallible_system() {
|
||||
fn sys() -> Result<()> {
|
||||
Err("error")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let mut world = World::new();
|
||||
let fallible_system_id = world.register_system(sys);
|
||||
let output = world.run_system(fallible_system_id);
|
||||
assert!(matches!(output, Ok(Err(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exclusive_system() {
|
||||
let mut world = World::new();
|
||||
@ -751,19 +764,54 @@ mod tests {
|
||||
assert!(matches!(output, Ok(x) if x == four()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cached_fallible_system() {
|
||||
fn sys() -> Result<()> {
|
||||
Err("error")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let mut world = World::new();
|
||||
let fallible_system_id = world.register_system_cached(sys);
|
||||
let output = world.run_system(fallible_system_id);
|
||||
assert!(matches!(output, Ok(Err(_))));
|
||||
let output = world.run_system_cached(sys);
|
||||
assert!(matches!(output, Ok(Err(_))));
|
||||
let output = world.run_system_cached_with(sys, ());
|
||||
assert!(matches!(output, Ok(Err(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cached_system_commands() {
|
||||
fn sys(mut counter: ResMut<Counter>) {
|
||||
counter.0 = 1;
|
||||
counter.0 += 1;
|
||||
}
|
||||
|
||||
let mut world = World::new();
|
||||
world.insert_resource(Counter(0));
|
||||
|
||||
world.commands().run_system_cached(sys);
|
||||
world.flush_commands();
|
||||
|
||||
assert_eq!(world.resource::<Counter>().0, 1);
|
||||
world.commands().run_system_cached_with(sys, ());
|
||||
world.flush_commands();
|
||||
assert_eq!(world.resource::<Counter>().0, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cached_fallible_system_commands() {
|
||||
fn sys(mut counter: ResMut<Counter>) -> Result {
|
||||
counter.0 += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let mut world = World::new();
|
||||
world.insert_resource(Counter(0));
|
||||
world.commands().run_system_cached(sys);
|
||||
world.flush_commands();
|
||||
assert_eq!(world.resource::<Counter>().0, 1);
|
||||
world.commands().run_system_cached_with(sys, ());
|
||||
world.flush_commands();
|
||||
assert_eq!(world.resource::<Counter>().0, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user