10个版本 (主要破坏)
7.0.0 | 2024年2月18日 |
---|---|
6.0.0 | 2024年1月29日 |
5.0.0 | 2023年11月4日 |
4.3.0 | 2023年10月13日 |
0.1.0 | 2022年9月7日 |
#42 in 游戏开发
每月下载量755
用于9个库(8 直接)
39KB
184 行
Bevy系统错误处理
使用sysfail
宏属性装饰你的bevy系统以处理失败。
之前
use bevy::prelude::*;
use bevy::utils::Duration;
use thiserror::Error;
#[derive(Error, Debug)]
enum GizmoError {
#[error("A Gizmo error")]
Error,
}
#[derive(Debug, PartialEq, Eq, Hash, SystemSet, Clone)]
enum TransformGizmoSystem { Drag, Place }
fn main() {
let mut app = App::new();
app.add_plugins(bevy::time::TimePlugin)
.add_systems(Update, (
drag_gizmo
.pipe(print_gizmo_error)
.in_set(TransformGizmoSystem::Drag),
delete_gizmo
.pipe(|In(_)| {})
.after(TransformGizmoSystem::Place),
place_gizmo
.pipe(print_gizmo_error)
.in_set(TransformGizmoSystem::Place)
.after(TransformGizmoSystem::Drag),
));
app.update();
}
fn print_gizmo_error(
In(result): In<Result<(), Box<dyn std::error::Error>>>,
mut last_error_occurence: Local<Option<Duration>>,
time: Res<Time>,
) {
// error boilerplate, may include
// - avoiding printing multiple times the same error
// - Formatting and chosing the log level
}
fn drag_gizmo(time: Res<Time>) -> Result<(), Box<dyn std::error::Error>> {
println!("drag time is: {}", time.elapsed_seconds());
let _ = Err(GizmoError::Error)?;
println!("This will never print");
Ok(())
}
fn place_gizmo() -> Result<(), Box<dyn std::error::Error>> {
let () = Result::<(), &'static str>::Ok(())?;
println!("this line should actually show up");
let _ = Err("Ah, some creative use of info logging I see")?;
Ok(())
}
fn delete_gizmo(time: Res<Time>) -> Option<()> {
println!("delete time is: {}", time.elapsed_seconds());
let _ = None?;
println!("This will never print");
Some(())
}
之后
use bevy::prelude::*;
use bevy_mod_sysfail::prelude::*;
use thiserror::Error;
#[derive(Error, Debug)]
enum GizmoError {
#[error("A Gizmo error")]
Error,
}
fn main() {
let mut app = App::new();
app.add_plugins(bevy::time::TimePlugin)
.add_systems(Update, (
drag_gizmo,
delete_gizmo.after(place_gizmo),
place_gizmo.after(drag_gizmo)
));
app.update();
}
#[sysfail]
fn drag_gizmo(time: Res<Time>) {
println!("drag time is: {}", time.elapsed_seconds());
let _ = Err(GizmoError::Error)?;
println!("This will never print");
}
#[sysfail(Log<&'static str, Info>)]
fn place_gizmo() {
let () = Result::<(), &'static str>::Ok(())?;
println!("this line should actually show up");
let _ = Err("Ah, some creative use of info logging I see")?;
}
#[sysfail(Ignore)]
fn delete_gizmo(time: Res<Time>) {
println!("delete time is: {}", time.elapsed_seconds());
let _ = Err(342_i32)?;
println!("This will never print");
}
sysfail
属性
sysfail
是一个属性宏,可以应用于系统以定义错误处理。与pipe
不同,这直接在定义位置进行,而不是在添加到应用时进行。因此,可以一目了然地看到系统中正在发生什么类型的错误处理,它还允许使用系统名称作为系统依赖指定中的标签。
sysfail(E)
系统返回类型为Result<(), E>
的值。返回类型由宏添加,因此不要自己添加!
E
是实现了Failure
特质的类型。bevy_mod_sysfail
导出了一些实现了Failure
的类型
Log<Err, Lvl = Warn>
:将Err
记录到跟踪日志器。- 第一种类型参数
Err
实现了Dedup
特性。您可以为自定义类型实现Dedup
,但您始终可以使用已实现Dedup
的类型,如anyhow::Error
、Box<dyn std::error::Error>
和&'static str
。 - 第二种类型参数指定了日志级别。它是可选的,默认为
Warn
- 第一种类型参数
LogSimply
:与Log
类似,但没有去重。Emit<Ev>
:当系统返回Err
时,会发出Ev
bevyEvent
。Ignore
:忽略错误,就像什么都没发生一样。
示例用法
use bevy::prelude::*;
use bevy_mod_sysfail::prelude::*;
use thiserror::Error;
// -- Log a value --
#[derive(Error, Debug)]
enum MyCustomError {
#[error("A Custom error")]
Error,
}
// Equivalent to #[sysfail(Log<Box<dyn std::error::Error>>)]
#[sysfail]
fn generic_failure() { /* ... */ }
#[sysfail(Log<&'static str>)]
fn log_a_str_message() {
let _ = Err("Yep, just like that")?;
}
#[sysfail(Log<anyhow::Error>)]
fn log_an_anyhow_error() {
let _ = Err(MyCustomError::Error)?;
}
#[sysfail(LogSimply<MyCustomError, Trace>)]
fn log_trace_on_failure() { /* ... */ }
#[sysfail(LogSimply<MyCustomError, Error>)]
fn log_error_on_failure() { /* ... */ }
// -- Emit an event --
use bevy::app::AppExit;
#[derive(Event)]
enum ChangeMenu {
Main,
Tools,
}
#[sysfail(Emit<ChangeMenu>)]
fn change_menu() { /* ... */ }
#[sysfail(Emit<AppExit>)]
fn quit_app_on_error() { /* ... */ }
// -- Ignore all errors --
#[sysfail(Ignore)]
fn do_not_care_about_failure() { /* ... */ }
独占系统
对于独占系统,使用 #[exclusive_sysfail]
宏。请注意,只有 Failure<Param = ()>
与独占系统一起工作。这排除了 Log
,所以请确保使用 LogSimply
。
自定义处理
bevy_mod_sysfail
不仅限于预定义的 Failure
集合,您可以通过自行实现来自定义。请参阅 自定义错误示例。
变更日志
请参阅 变更日志。
版本矩阵
bevy | 最新支持版本 |
---|---|
0.13 | 7.0.0 |
0.12 | 6.0.0 |
0.11 | 4.3.0 |
0.10 | 2.0.0 |
0.9 | 1.1.0 |
0.8 | 0.1.0 |
许可证
版权所有 © 2022 Nicola Papale
本软件根据 Apache 2.0 许可证授权。
依赖关系
~8–36MB
~533K SLoC