Skip to content

Commit

Permalink
[Fixes bevyengine#6224] Add logging variants of system piping (bevyen…
Browse files Browse the repository at this point in the history
…gine#6751)

# Objective

Fixes bevyengine#6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand bevyengine#5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error.

## Solution

* Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``. 
* Modified and added tests for these under examples in ``system_piping.rs``.
  • Loading branch information
Edwox authored and alradish committed Jan 22, 2023
1 parent fe73dd0 commit 1bad991
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 4 deletions.
7 changes: 4 additions & 3 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ pub mod prelude {
Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
},
system::{
adapter as system_adapter, Commands, In, IntoPipeSystem, IntoSystem, Local, NonSend,
NonSendMut, ParallelCommands, ParamSet, Query, RemovedComponents, Res, ResMut,
Resource, System, SystemParamFunction,
adapter as system_adapter,
adapter::{dbg, error, ignore, info, unwrap, warn},
Commands, In, IntoPipeSystem, IntoSystem, Local, NonSend, NonSendMut, ParallelCommands,
ParamSet, Query, RemovedComponents, Res, ResMut, Resource, System, SystemParamFunction,
},
world::{FromWorld, Mut, World},
};
Expand Down
137 changes: 137 additions & 0 deletions crates/bevy_ecs/src/system/system_piping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ where
/// A collection of common adapters for [piping](super::PipeSystem) the result of a system.
pub mod adapter {
use crate::system::In;
use bevy_utils::tracing;
use std::fmt::Debug;

/// Converts a regular function into a system adapter.
Expand Down Expand Up @@ -232,6 +233,142 @@ pub mod adapter {
res.unwrap()
}

/// System adapter that utilizes the [`bevy_utils::tracing::info!`] macro to print system information.
///
/// # Examples
///
/// ```
/// use bevy_ecs::prelude::*;
/// #
/// # #[derive(StageLabel)]
/// # enum CoreStage { Update };
///
/// // Building a new schedule/app...
/// # use bevy_ecs::schedule::SystemStage;
/// # let mut sched = Schedule::default(); sched
/// # .add_stage(CoreStage::Update, SystemStage::parallel())
/// .add_system_to_stage(
/// CoreStage::Update,
/// // Prints system information.
/// data_pipe_system.pipe(system_adapter::info)
/// )
/// // ...
/// # ;
/// # let mut world = World::new();
/// # sched.run(&mut world);
///
/// // A system that returns a String output.
/// fn data_pipe_system() -> String {
/// "42".to_string()
/// }
/// ```
pub fn info<T: Debug>(In(data): In<T>) {
tracing::info!("{:?}", data);
}

/// System adapter that utilizes the [`bevy_utils::tracing::debug!`] macro to print the output of a system.
///
/// # Examples
///
/// ```
/// use bevy_ecs::prelude::*;
/// #
/// # #[derive(StageLabel)]
/// # enum CoreStage { Update };
///
/// // Building a new schedule/app...
/// # use bevy_ecs::schedule::SystemStage;
/// # let mut sched = Schedule::default(); sched
/// # .add_stage(CoreStage::Update, SystemStage::parallel())
/// .add_system_to_stage(
/// CoreStage::Update,
/// // Prints debug data from system.
/// parse_message_system.pipe(system_adapter::dbg)
/// )
/// // ...
/// # ;
/// # let mut world = World::new();
/// # sched.run(&mut world);
///
/// // A system that returns a Result<usize, String> output.
/// fn parse_message_system() -> Result<usize, std::num::ParseIntError> {
/// Ok("42".parse()?)
/// }
/// ```
pub fn dbg<T: Debug>(In(data): In<T>) {
tracing::debug!("{:?}", data);
}

/// System adapter that utilizes the [`bevy_utils::tracing::warn!`] macro to print the output of a system.
///
/// # Examples
///
/// ```
/// use bevy_ecs::prelude::*;
/// #
/// # #[derive(StageLabel)]
/// # enum CoreStage { Update };
///
/// // Building a new schedule/app...
/// # use bevy_ecs::schedule::SystemStage;
/// # let mut sched = Schedule::default(); sched
/// # .add_stage(CoreStage::Update, SystemStage::parallel())
/// .add_system_to_stage(
/// CoreStage::Update,
/// // Prints system warning if system returns an error.
/// warning_pipe_system.pipe(system_adapter::warn)
/// )
/// // ...
/// # ;
/// # let mut world = World::new();
/// # sched.run(&mut world);
///
/// // A system that returns a Result<(), String> output.
/// fn warning_pipe_system() -> Result<(), String> {
/// Err("Got to rusty?".to_string())
/// }
/// ```
pub fn warn<E: Debug>(In(res): In<Result<(), E>>) {
if let Err(warn) = res {
tracing::warn!("{:?}", warn);
}
}

/// System adapter that utilizes the [`bevy_utils::tracing::error!`] macro to print the output of a system.
///
/// # Examples
///
/// ```
/// use bevy_ecs::prelude::*;
/// #
/// # #[derive(StageLabel)]
/// # enum CoreStage { Update };
///
/// // Building a new schedule/app...
/// # use bevy_ecs::schedule::SystemStage;
/// # let mut sched = Schedule::default(); sched
/// # .add_stage(CoreStage::Update, SystemStage::parallel())
/// .add_system_to_stage(
/// CoreStage::Update,
/// // Prints system error if system fails.
/// parse_error_message_system.pipe(system_adapter::error)
/// )
/// // ...
/// # ;
/// # let mut world = World::new();
/// # sched.run(&mut world);
///
/// // A system that returns a Result<())> output.
/// fn parse_error_message_system() -> Result<(), String> {
/// Err("Some error".to_owned())
/// }
/// ```
pub fn error<E: Debug>(In(res): In<Result<(), E>>) {
if let Err(error) = res {
tracing::error!("{:?}", error);
}
}

/// System adapter that ignores the output of the previous system in a pipe.
/// This is useful for fallible systems that should simply return early in case of an `Err`/`None`.
///
Expand Down
36 changes: 35 additions & 1 deletion examples/ecs/system_piping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,43 @@
use anyhow::Result;
use bevy::prelude::*;

use bevy::log::LogPlugin;
use bevy::utils::tracing::Level;

fn main() {
App::new()
.insert_resource(Message("42".to_string()))
.insert_resource(OptionalWarning(Err("Got to rusty?".to_string())))
.add_plugin(LogPlugin {
level: Level::TRACE,
filter: "".to_string(),
})
.add_system(parse_message_system.pipe(handler_system))
.add_system(data_pipe_system.pipe(info))
.add_system(parse_message_system.pipe(dbg))
.add_system(warning_pipe_system.pipe(warn))
.add_system(parse_error_message_system.pipe(error))
.add_system(parse_message_system.pipe(ignore))
.run();
}

#[derive(Resource, Deref)]
struct Message(String);

// this system produces a Result<usize> output by trying to parse the Message resource
#[derive(Resource, Deref)]
struct OptionalWarning(Result<(), String>);

// This system produces a Result<usize> output by trying to parse the Message resource.
fn parse_message_system(message: Res<Message>) -> Result<usize> {
Ok(message.parse::<usize>()?)
}

// This system produces a Result<()> output by trying to parse the Message resource.
fn parse_error_message_system(message: Res<Message>) -> Result<()> {
message.parse::<usize>()?;
Ok(())
}

// This system takes a Result<usize> input and either prints the parsed value or the error message
// Try changing the Message resource to something that isn't an integer. You should see the error
// message printed.
Expand All @@ -28,3 +50,15 @@ fn handler_system(In(result): In<Result<usize>>) {
Err(err) => println!("encountered an error: {err:?}"),
}
}

// This system produces a String output by trying to clone the String from the Message resource.
fn data_pipe_system(message: Res<Message>) -> String {
message.0.clone()
}

// This system produces an Result<String> output by trying to extract a String from the
// OptionalWarning resource. Try changing the OptionalWarning resource to None. You should
// not see the warning message printed.
fn warning_pipe_system(message: Res<OptionalWarning>) -> Result<(), String> {
message.0.clone()
}

0 comments on commit 1bad991

Please sign in to comment.