2022-05-16 13:53:20 +00:00
|
|
|
//! This example illustrates how to use logs in bevy.
|
|
|
|
|
2024-09-24 11:42:59 +00:00
|
|
|
use bevy::{log::once, prelude::*};
|
2020-11-13 01:23:57 +00:00
|
|
|
|
|
|
|
fn main() {
|
2021-07-27 20:21:06 +00:00
|
|
|
App::new()
|
Use plugin setup for resource only used at setup time (#6360)
# Objective
- Build on #6336 for more plugin configurations
## Solution
- `LogSettings`, `ImageSettings` and `DefaultTaskPoolOptions` are now plugins settings rather than resources
---
## Changelog
- `LogSettings` plugin settings have been move to `LogPlugin`, `ImageSettings` to `ImagePlugin` and `DefaultTaskPoolOptions` to `CorePlugin`
## Migration Guide
The `LogSettings` settings have been moved from a resource to `LogPlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(LogSettings {
level: Level::DEBUG,
filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(LogPlugin {
level: Level::DEBUG,
filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
}))
```
The `ImageSettings` settings have been moved from a resource to `ImagePlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(ImageSettings::default_nearest())
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
```
The `DefaultTaskPoolOptions` settings have been moved from a resource to `CorePlugin::task_pool_options`:
```rust
// Old (Bevy 0.8)
app
.insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(CorePlugin {
task_pool_options: TaskPoolOptions::with_num_threads(4),
}))
```
2022-10-25 22:19:34 +00:00
|
|
|
.add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
|
|
|
|
// Uncomment this to override the default log settings:
|
|
|
|
// level: bevy::log::Level::TRACE,
|
|
|
|
// filter: "wgpu=warn,bevy_ecs=info".to_string(),
|
|
|
|
..default()
|
|
|
|
}))
|
2024-01-02 03:02:56 +00:00
|
|
|
.add_systems(Startup, setup)
|
2023-03-18 01:45:34 +00:00
|
|
|
.add_systems(Update, log_system)
|
Add helper macro's for logging only once (#10808)
# Objective
Fixes #10291
This adds a way to easily log messages once within system which are
called every frame.
## Solution
Opted for a macro-based approach. The fact that the 'once' call is
tracked per call site makes the `log_once!()` macro very versatile and
easy-to-use. I suspect it will be very handy for all of us, but
especially beginners, to get some initial feedback from systems without
spamming up the place!
I've made the macro's return its internal `has_fired` state, for
situations in which that might be useful to know (trigger something else
alongside the log, for example).
Please let me know if I placed the macro's in the right location, and if
you would like me to do something more clever with the macro's
themselves, since its looking quite copy-pastey at the moment. I've
tried ways to replace 5 with 1 macro's, but no success yet.
One downside of this approach is: Say you wish to warn the user if a
resource is invalid. In this situation, the
`resource.is_valid()` check would still be performed every frame:
```rust
fn my_system(my_res: Res<MyResource>) {
if !my_res.is_valid() {
warn_once!("resource is invalid!");
}
}
```
If you want to prevent that, you would still need to introduce a local
boolean. I don't think this is a very big deal, as expensive checks
shouldn't be called every frame in any case.
## Changelog
Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`,
and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
|
|
|
.add_systems(Update, log_once_system)
|
2024-01-02 03:02:56 +00:00
|
|
|
.add_systems(Update, panic_on_p)
|
2020-11-13 01:23:57 +00:00
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
2024-01-02 03:02:56 +00:00
|
|
|
fn setup(mut commands: Commands) {
|
2024-10-05 01:59:52 +00:00
|
|
|
commands.spawn(Camera2d);
|
Text rework (#15591)
**Ready for review. Examples migration progress: 100%.**
# Objective
- Implement https://github.com/bevyengine/bevy/discussions/15014
## Solution
This implements [cart's
proposal](https://github.com/bevyengine/bevy/discussions/15014#discussioncomment-10574459)
faithfully except for one change. I separated `TextSpan` from
`TextSpan2d` because `TextSpan` needs to require the `GhostNode`
component, which is a `bevy_ui` component only usable by UI.
Extra changes:
- Added `EntityCommands::commands_mut` that returns a mutable reference.
This is a blocker for extension methods that return something other than
`self`. Note that `sickle_ui`'s `UiBuilder::commands` returns a mutable
reference for this reason.
## Testing
- [x] Text examples all work.
---
## Showcase
TODO: showcase-worthy
## Migration Guide
TODO: very breaking
### Accessing text spans by index
Text sections are now text sections on different entities in a
hierarchy, Use the new `TextReader` and `TextWriter` system parameters
to access spans by index.
Before:
```rust
fn refresh_text(mut query: Query<&mut Text, With<TimeText>>, time: Res<Time>) {
let text = query.single_mut();
text.sections[1].value = format_time(time.elapsed());
}
```
After:
```rust
fn refresh_text(
query: Query<Entity, With<TimeText>>,
mut writer: UiTextWriter,
time: Res<Time>
) {
let entity = query.single();
*writer.text(entity, 1) = format_time(time.elapsed());
}
```
### Iterating text spans
Text spans are now entities in a hierarchy, so the new `UiTextReader`
and `UiTextWriter` system parameters provide ways to iterate that
hierarchy. The `UiTextReader::iter` method will give you a normal
iterator over spans, and `UiTextWriter::for_each` lets you visit each of
the spans.
---------
Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-09 18:35:36 +00:00
|
|
|
commands.spawn((
|
|
|
|
Text::new("Press P to panic"),
|
|
|
|
Style {
|
2024-05-30 23:11:23 +00:00
|
|
|
position_type: PositionType::Absolute,
|
|
|
|
top: Val::Px(12.0),
|
|
|
|
left: Val::Px(12.0),
|
|
|
|
..default()
|
|
|
|
},
|
Text rework (#15591)
**Ready for review. Examples migration progress: 100%.**
# Objective
- Implement https://github.com/bevyengine/bevy/discussions/15014
## Solution
This implements [cart's
proposal](https://github.com/bevyengine/bevy/discussions/15014#discussioncomment-10574459)
faithfully except for one change. I separated `TextSpan` from
`TextSpan2d` because `TextSpan` needs to require the `GhostNode`
component, which is a `bevy_ui` component only usable by UI.
Extra changes:
- Added `EntityCommands::commands_mut` that returns a mutable reference.
This is a blocker for extension methods that return something other than
`self`. Note that `sickle_ui`'s `UiBuilder::commands` returns a mutable
reference for this reason.
## Testing
- [x] Text examples all work.
---
## Showcase
TODO: showcase-worthy
## Migration Guide
TODO: very breaking
### Accessing text spans by index
Text sections are now text sections on different entities in a
hierarchy, Use the new `TextReader` and `TextWriter` system parameters
to access spans by index.
Before:
```rust
fn refresh_text(mut query: Query<&mut Text, With<TimeText>>, time: Res<Time>) {
let text = query.single_mut();
text.sections[1].value = format_time(time.elapsed());
}
```
After:
```rust
fn refresh_text(
query: Query<Entity, With<TimeText>>,
mut writer: UiTextWriter,
time: Res<Time>
) {
let entity = query.single();
*writer.text(entity, 1) = format_time(time.elapsed());
}
```
### Iterating text spans
Text spans are now entities in a hierarchy, so the new `UiTextReader`
and `UiTextWriter` system parameters provide ways to iterate that
hierarchy. The `UiTextReader::iter` method will give you a normal
iterator over spans, and `UiTextWriter::for_each` lets you visit each of
the spans.
---------
Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-09 18:35:36 +00:00
|
|
|
));
|
2024-01-02 03:02:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn panic_on_p(keys: Res<ButtonInput<KeyCode>>) {
|
|
|
|
if keys.just_pressed(KeyCode::KeyP) {
|
|
|
|
panic!("P pressed, panicking");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-13 01:23:57 +00:00
|
|
|
fn log_system() {
|
2021-03-11 00:27:30 +00:00
|
|
|
// here is how you write new logs at each "log level" (in "least important" to "most important"
|
|
|
|
// order)
|
2020-11-13 01:23:57 +00:00
|
|
|
trace!("very noisy");
|
|
|
|
debug!("helpful for debugging");
|
|
|
|
info!("helpful information that is worth printing by default");
|
|
|
|
warn!("something bad happened that isn't a failure, but thats worth calling out");
|
|
|
|
error!("something failed");
|
|
|
|
|
|
|
|
// by default, trace and debug logs are ignored because they are "noisy"
|
Use plugin setup for resource only used at setup time (#6360)
# Objective
- Build on #6336 for more plugin configurations
## Solution
- `LogSettings`, `ImageSettings` and `DefaultTaskPoolOptions` are now plugins settings rather than resources
---
## Changelog
- `LogSettings` plugin settings have been move to `LogPlugin`, `ImageSettings` to `ImagePlugin` and `DefaultTaskPoolOptions` to `CorePlugin`
## Migration Guide
The `LogSettings` settings have been moved from a resource to `LogPlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(LogSettings {
level: Level::DEBUG,
filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
})
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(LogPlugin {
level: Level::DEBUG,
filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
}))
```
The `ImageSettings` settings have been moved from a resource to `ImagePlugin` configuration:
```rust
// Old (Bevy 0.8)
app
.insert_resource(ImageSettings::default_nearest())
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
```
The `DefaultTaskPoolOptions` settings have been moved from a resource to `CorePlugin::task_pool_options`:
```rust
// Old (Bevy 0.8)
app
.insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
.add_plugins(DefaultPlugins)
// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(CorePlugin {
task_pool_options: TaskPoolOptions::with_num_threads(4),
}))
```
2022-10-25 22:19:34 +00:00
|
|
|
// you can control what level is logged by setting up the LogPlugin
|
2020-11-13 01:23:57 +00:00
|
|
|
// alternatively you can set the log level via the RUST_LOG=LEVEL environment variable
|
|
|
|
// ex: RUST_LOG=trace, RUST_LOG=info,bevy_ecs=warn
|
|
|
|
// the format used here is super flexible. check out this documentation for more info:
|
|
|
|
// https://docs.rs/tracing-subscriber/*/tracing_subscriber/filter/struct.EnvFilter.html
|
|
|
|
}
|
Add helper macro's for logging only once (#10808)
# Objective
Fixes #10291
This adds a way to easily log messages once within system which are
called every frame.
## Solution
Opted for a macro-based approach. The fact that the 'once' call is
tracked per call site makes the `log_once!()` macro very versatile and
easy-to-use. I suspect it will be very handy for all of us, but
especially beginners, to get some initial feedback from systems without
spamming up the place!
I've made the macro's return its internal `has_fired` state, for
situations in which that might be useful to know (trigger something else
alongside the log, for example).
Please let me know if I placed the macro's in the right location, and if
you would like me to do something more clever with the macro's
themselves, since its looking quite copy-pastey at the moment. I've
tried ways to replace 5 with 1 macro's, but no success yet.
One downside of this approach is: Say you wish to warn the user if a
resource is invalid. In this situation, the
`resource.is_valid()` check would still be performed every frame:
```rust
fn my_system(my_res: Res<MyResource>) {
if !my_res.is_valid() {
warn_once!("resource is invalid!");
}
}
```
If you want to prevent that, you would still need to introduce a local
boolean. I don't think this is a very big deal, as expensive checks
shouldn't be called every frame in any case.
## Changelog
Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`,
and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
|
|
|
|
|
|
|
fn log_once_system() {
|
|
|
|
// The 'once' variants of each log level are useful when a system is called every frame,
|
|
|
|
// but we still wish to inform the user only once. In other words, use these to prevent spam :)
|
|
|
|
|
|
|
|
trace_once!("one time noisy message");
|
|
|
|
debug_once!("one time debug message");
|
|
|
|
info_once!("some info which is printed only once");
|
|
|
|
warn_once!("some warning we wish to call out only once");
|
|
|
|
error_once!("some error we wish to report only once");
|
|
|
|
|
|
|
|
for i in 0..10 {
|
|
|
|
info_once!("logs once per call site, so this works just fine: {}", i);
|
|
|
|
}
|
|
|
|
|
2024-04-25 19:09:16 +00:00
|
|
|
// you can also use the `once!` macro directly,
|
|
|
|
// in situations where you want to do something expensive only once
|
|
|
|
// within the context of a continuous system.
|
Add helper macro's for logging only once (#10808)
# Objective
Fixes #10291
This adds a way to easily log messages once within system which are
called every frame.
## Solution
Opted for a macro-based approach. The fact that the 'once' call is
tracked per call site makes the `log_once!()` macro very versatile and
easy-to-use. I suspect it will be very handy for all of us, but
especially beginners, to get some initial feedback from systems without
spamming up the place!
I've made the macro's return its internal `has_fired` state, for
situations in which that might be useful to know (trigger something else
alongside the log, for example).
Please let me know if I placed the macro's in the right location, and if
you would like me to do something more clever with the macro's
themselves, since its looking quite copy-pastey at the moment. I've
tried ways to replace 5 with 1 macro's, but no success yet.
One downside of this approach is: Say you wish to warn the user if a
resource is invalid. In this situation, the
`resource.is_valid()` check would still be performed every frame:
```rust
fn my_system(my_res: Res<MyResource>) {
if !my_res.is_valid() {
warn_once!("resource is invalid!");
}
}
```
If you want to prevent that, you would still need to introduce a local
boolean. I don't think this is a very big deal, as expensive checks
shouldn't be called every frame in any case.
## Changelog
Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`,
and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
|
|
|
once!({
|
|
|
|
info!("doing expensive things");
|
|
|
|
let mut a: u64 = 0;
|
|
|
|
for i in 0..100000000 {
|
|
|
|
a += i;
|
|
|
|
}
|
|
|
|
info!("result of some expensive one time calculation: {}", a);
|
|
|
|
});
|
|
|
|
}
|