Skip to content

Commit 0b91637

Browse files
committed
Merge queue and queue_fallible
1 parent ffe5cf4 commit 0b91637

File tree

3 files changed

+60
-63
lines changed

3 files changed

+60
-63
lines changed

crates/bevy_ecs/src/system/commands/command.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ where
6565

6666
/// Takes a [`Command`] that returns a Result and uses a given error handler function to convert it into
6767
/// a [`Command`] that internally handles an error if it occurs and returns `()`.
68-
pub trait HandleError {
68+
pub trait HandleError<T = ()> {
6969
/// Takes a [`Command`] that returns a Result and uses a given error handler function to convert it into
7070
/// a [`Command`] that internally handles an error if it occurs and returns `()`.
7171
fn handle_error_with(self, error_handler: fn(&mut World, Error)) -> impl Command;
@@ -79,23 +79,26 @@ pub trait HandleError {
7979
}
8080
}
8181

82-
impl<C: Command<Result>> HandleError for C {
82+
impl<C: Command<Result<T, E>>, T, E: Into<Error>> HandleError<Result<T, E>> for C {
8383
fn handle_error_with(self, error_handler: fn(&mut World, Error)) -> impl Command {
8484
move |world: &mut World| match self.apply(world) {
8585
Ok(_) => {}
86-
Err(err) => (error_handler)(world, err),
86+
Err(err) => (error_handler)(world, err.into()),
8787
}
8888
}
8989
}
9090

91-
/// Takes a [`Command`] that returns a [`Result`] with an error that can be converted into the [`Error`] type
92-
/// and returns a [`Command`] that internally converts that error to [`Error`] (if it occurs).
93-
pub fn map_command_err<T, E: Into<Error>>(
94-
command: impl Command<Result<T, E>>,
95-
) -> impl Command<Result<T, Error>> {
96-
move |world: &mut World| match command.apply(world) {
97-
Ok(result) => Ok(result),
98-
Err(err) => Err(err.into()),
91+
impl<C: Command> HandleError for C {
92+
#[inline]
93+
fn handle_error_with(self, _error_handler: fn(&mut World, Error)) -> impl Command {
94+
self
95+
}
96+
#[inline]
97+
fn handle_error(self) -> impl Command
98+
where
99+
Self: Sized,
100+
{
101+
self
99102
}
100103
}
101104

crates/bevy_ecs/src/system/commands/entity_command.rs

+39-19
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
component::{Component, ComponentId, ComponentInfo},
1616
entity::{Entity, EntityCloneBuilder},
1717
event::Event,
18-
system::{error_handler, Command, IntoObserverSystem},
18+
system::{error_handler, Command, HandleError, IntoObserverSystem},
1919
world::{error::EntityFetchError, EntityWorldMut, FromWorld, World},
2020
};
2121
use bevy_ptr::OwningPtr;
@@ -86,23 +86,34 @@ pub trait EntityCommand<T = ()>: Send + 'static {
8686
pub trait CommandWithEntity<T> {
8787
/// Passes in a specific entity to an [`EntityCommand`], resulting in a [`Command`] that
8888
/// internally runs the [`EntityCommand`] on that entity.
89-
fn with_entity(self, entity: Entity) -> impl Command<T>;
89+
fn with_entity(self, entity: Entity) -> impl Command<T> + HandleError<T>;
9090
}
9191

92-
impl<C: EntityCommand<()>> CommandWithEntity<Result<(), EntityFetchError>> for C {
93-
fn with_entity(self, entity: Entity) -> impl Command<Result<(), EntityFetchError>> {
94-
move |world: &mut World| {
92+
impl<C: EntityCommand> CommandWithEntity<Result<(), EntityFetchError>> for C {
93+
fn with_entity(
94+
self,
95+
entity: Entity,
96+
) -> impl Command<Result<(), EntityFetchError>> + HandleError<Result<(), EntityFetchError>>
97+
{
98+
move |world: &mut World| -> Result<(), EntityFetchError> {
9599
let entity = world.get_entity_mut(entity)?;
96100
self.apply(entity);
97101
Ok(())
98102
}
99103
}
100104
}
101105

102-
impl<C: EntityCommand<Result<T, Err>>, T, Err> CommandWithEntity<Result<T, EntityCommandError<Err>>>
103-
for C
106+
impl<
107+
C: EntityCommand<Result<T, Err>>,
108+
T,
109+
Err: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static,
110+
> CommandWithEntity<Result<T, EntityCommandError<Err>>> for C
104111
{
105-
fn with_entity(self, entity: Entity) -> impl Command<Result<T, EntityCommandError<Err>>> {
112+
fn with_entity(
113+
self,
114+
entity: Entity,
115+
) -> impl Command<Result<T, EntityCommandError<Err>>> + HandleError<Result<T, EntityCommandError<Err>>>
116+
{
106117
move |world: &mut World| {
107118
let entity = world.get_entity_mut(entity)?;
108119
match self.apply(entity) {
@@ -115,7 +126,7 @@ impl<C: EntityCommand<Result<T, Err>>, T, Err> CommandWithEntity<Result<T, Entit
115126

116127
/// Takes a [`EntityCommand`] that returns a Result and uses a given error handler function to convert it into
117128
/// a [`EntityCommand`] that internally handles an error if it occurs and returns `()`.
118-
pub trait HandleEntityError {
129+
pub trait HandleEntityError<T = ()> {
119130
/// Takes a [`EntityCommand`] that returns a Result and uses a given error handler function to convert it into
120131
/// a [`EntityCommand`] that internally handles an error if it occurs and returns `()`.
121132
fn handle_error_with(
@@ -132,7 +143,9 @@ pub trait HandleEntityError {
132143
}
133144
}
134145

135-
impl<C: EntityCommand<crate::result::Result>> HandleEntityError for C {
146+
impl<C: EntityCommand<crate::result::Result<T, E>>, T, E: Into<crate::result::Error>>
147+
HandleEntityError<crate::result::Result<T, E>> for C
148+
{
136149
fn handle_error_with(
137150
self,
138151
error_handler: fn(&mut World, crate::result::Error),
@@ -146,20 +159,27 @@ impl<C: EntityCommand<crate::result::Result>> HandleEntityError for C {
146159
// SAFETY: location has not changed and entity is valid
147160
match self.apply(unsafe { EntityWorldMut::new(world, id, location) }) {
148161
Ok(_) => {}
149-
Err(err) => (error_handler)(world, err),
162+
Err(err) => (error_handler)(world, err.into()),
150163
}
151164
}
152165
}
153166
}
154167

155-
/// Takes a [`EntityCommand`] that returns a [`Result`] with an error that can be converted into the [`Error`] type
156-
/// and returns a [`EntityCommand`] that internally converts that error to [`Error`] (if it occurs).
157-
pub fn map_entity_command_err<T, E: Into<crate::result::Error>>(
158-
command: impl EntityCommand<Result<T, E>>,
159-
) -> impl EntityCommand<Result<T, crate::result::Error>> {
160-
move |entity: EntityWorldMut| match command.apply(entity) {
161-
Ok(result) => Ok(result),
162-
Err(err) => Err(err.into()),
168+
impl<C: EntityCommand> HandleEntityError for C {
169+
#[inline]
170+
fn handle_error_with(
171+
self,
172+
_error_handler: fn(&mut World, crate::result::Error),
173+
) -> impl EntityCommand {
174+
self
175+
}
176+
177+
#[inline]
178+
fn handle_error(self) -> impl EntityCommand
179+
where
180+
Self: Sized,
181+
{
182+
self
163183
}
164184
}
165185

crates/bevy_ecs/src/system/commands/mod.rs

+7-33
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@ use crate::{
2626
entity::{Entities, Entity, EntityCloneBuilder},
2727
event::Event,
2828
observer::{Observer, TriggerTargets},
29-
result::{Error, Result},
3029
schedule::ScheduleLabel,
3130
system::{
32-
command::map_command_err, entity_command::map_entity_command_err, input::SystemInput,
33-
Deferred, IntoObserverSystem, IntoSystem, RegisteredSystem, Resource, SystemId,
31+
input::SystemInput, Deferred, IntoObserverSystem, IntoSystem, RegisteredSystem, Resource,
32+
SystemId,
3433
},
3534
world::{
3635
command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,
@@ -589,7 +588,8 @@ impl<'w, 's> Commands<'w, 's> {
589588
/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
590589
/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
591590
/// ```
592-
pub fn queue<C: Command>(&mut self, command: C) {
591+
pub fn queue<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {
592+
let command = command.handle_error();
593593
match &mut self.queue {
594594
InternalQueue::CommandQueue(queue) => {
595595
queue.push(command);
@@ -604,18 +604,6 @@ impl<'w, 's> Commands<'w, 's> {
604604
}
605605
}
606606

607-
/// Pushes a generic [`Command`] to the command queue with error handling.
608-
///
609-
/// The command can be:
610-
/// - A custom struct that implements [`Command`].
611-
/// - A closure or function that has the signature [`(&mut World)`](World)`->`[`Result`](crate::result::Result).
612-
/// - A built-in command from the [`command`] module.
613-
///
614-
/// This will use the default error handler. See [`Command`] for details on error handling.
615-
pub fn queue_fallible<E: Into<Error>>(&mut self, command: impl Command<Result<(), E>>) {
616-
self.queue(map_command_err(command).handle_error());
617-
}
618-
619607
/// Pushes a [`Command`] to the queue for creating entities, if needed,
620608
/// and for adding a bundle to each entity.
621609
///
@@ -1666,25 +1654,11 @@ impl<'a> EntityCommands<'a> {
16661654
/// # }
16671655
/// # bevy_ecs::system::assert_is_system(my_system);
16681656
/// ```
1669-
pub fn queue(&mut self, command: impl EntityCommand) -> &mut Self {
1670-
self.commands
1671-
.queue_fallible(command.with_entity(self.entity));
1672-
self
1673-
}
1674-
1675-
/// Pushes a fallible [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
1676-
///
1677-
/// The command can be:
1678-
/// - A custom struct that implements [`EntityCommand`].
1679-
/// - A closure or function that matches the following signature:
1680-
/// - [`(EntityWorldMut)`](EntityWorldMut)`->` [`Result<(), E>`]
1681-
/// - A built-in command from the [`entity_command`] module.
1682-
pub fn queue_fallible<E: Into<Error>>(
1657+
pub fn queue<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(
16831658
&mut self,
1684-
command: impl EntityCommand<Result<(), E>>,
1659+
command: C,
16851660
) -> &mut Self {
1686-
self.commands
1687-
.queue_fallible(map_entity_command_err(command).with_entity(self.entity));
1661+
self.commands.queue(command.with_entity(self.entity));
16881662
self
16891663
}
16901664

0 commit comments

Comments
 (0)