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,
|
/// A [`Command`] that runs the given system,
|
||||||
/// caching its [`SystemId`] in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
|
/// 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
|
where
|
||||||
|
O: 'static,
|
||||||
M: 'static,
|
M: 'static,
|
||||||
S: IntoSystem<(), (), M> + Send + 'static,
|
S: IntoSystem<(), O, M> + Send + 'static,
|
||||||
{
|
{
|
||||||
move |world: &mut World| -> Result {
|
move |world: &mut World| -> Result {
|
||||||
world.run_system_cached(system)?;
|
world.run_system_cached(system)?;
|
||||||
@ -157,11 +158,15 @@ where
|
|||||||
|
|
||||||
/// A [`Command`] that runs the given system with the given input value,
|
/// A [`Command`] that runs the given system with the given input value,
|
||||||
/// caching its [`SystemId`] in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
|
/// 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
|
where
|
||||||
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
||||||
|
O: 'static,
|
||||||
M: 'static,
|
M: 'static,
|
||||||
S: IntoSystem<I, (), M> + Send + 'static,
|
S: IntoSystem<I, O, M> + Send + 'static,
|
||||||
{
|
{
|
||||||
move |world: &mut World| -> Result {
|
move |world: &mut World| -> Result {
|
||||||
world.run_system_cached_with(system, input)?;
|
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>
|
pub fn unregister_system<I, O>(system_id: SystemId<I, O>) -> impl Command<Result>
|
||||||
where
|
where
|
||||||
I: SystemInput + Send + 'static,
|
I: SystemInput + Send + 'static,
|
||||||
O: Send + 'static,
|
O: 'static,
|
||||||
{
|
{
|
||||||
move |world: &mut World| -> Result {
|
move |world: &mut World| -> Result {
|
||||||
world.unregister_system(system_id)?;
|
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),
|
/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
|
||||||
/// which will be handled by [logging the error at the `warn` level](warn).
|
/// 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));
|
self.queue(command::run_system(id).handle_error_with(warn));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +965,7 @@ impl<'w, 's> Commands<'w, 's> {
|
|||||||
) -> SystemId<I, O>
|
) -> SystemId<I, O>
|
||||||
where
|
where
|
||||||
I: SystemInput + Send + 'static,
|
I: SystemInput + Send + 'static,
|
||||||
O: Send + 'static,
|
O: 'static,
|
||||||
{
|
{
|
||||||
let entity = self.spawn_empty().id();
|
let entity = self.spawn_empty().id();
|
||||||
let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));
|
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>)
|
pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
|
||||||
where
|
where
|
||||||
I: SystemInput + Send + 'static,
|
I: SystemInput + Send + 'static,
|
||||||
O: Send + 'static,
|
O: 'static,
|
||||||
{
|
{
|
||||||
self.queue(command::unregister_system(system_id).handle_error_with(warn));
|
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`].
|
/// consider passing them in as inputs via [`Commands::run_system_cached_with`].
|
||||||
///
|
///
|
||||||
/// If that's not an option, consider [`Commands::register_system`] instead.
|
/// 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
|
where
|
||||||
|
O: 'static,
|
||||||
M: '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));
|
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.
|
/// consider passing them in as inputs.
|
||||||
///
|
///
|
||||||
/// If that's not an option, consider [`Commands::register_system`] instead.
|
/// 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
|
where
|
||||||
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
I: SystemInput<Inner<'static>: Send> + Send + 'static,
|
||||||
|
O: 'static,
|
||||||
M: '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));
|
self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));
|
||||||
}
|
}
|
||||||
|
@ -651,6 +651,19 @@ mod tests {
|
|||||||
assert_eq!(output, NonCopy(3));
|
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]
|
#[test]
|
||||||
fn exclusive_system() {
|
fn exclusive_system() {
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
@ -751,19 +764,54 @@ mod tests {
|
|||||||
assert!(matches!(output, Ok(x) if x == four()));
|
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]
|
#[test]
|
||||||
fn cached_system_commands() {
|
fn cached_system_commands() {
|
||||||
fn sys(mut counter: ResMut<Counter>) {
|
fn sys(mut counter: ResMut<Counter>) {
|
||||||
counter.0 = 1;
|
counter.0 += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
world.insert_resource(Counter(0));
|
world.insert_resource(Counter(0));
|
||||||
|
|
||||||
world.commands().run_system_cached(sys);
|
world.commands().run_system_cached(sys);
|
||||||
world.flush_commands();
|
world.flush_commands();
|
||||||
|
|
||||||
assert_eq!(world.resource::<Counter>().0, 1);
|
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]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user