Skip to content

Commit 0f0d2a3

Browse files
committed
Add support for tracking Meshes and Images.
1 parent a1af984 commit 0f0d2a3

19 files changed

+637
-69
lines changed

Cargo.toml

+44-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,48 @@ version = "0.0.1"
44
edition = "2021"
55

66
[dependencies]
7-
bevy = { version = "0.6", default-features = false, features = [] }
7+
bevy = { version = "0.6", default-features = false }
88
datasize = "0.2"
9+
10+
[dev-dependencies]
11+
maplit = "1"
12+
13+
[features]
14+
default = [
15+
"render"
16+
]
17+
18+
# Enables support for tracking Bevy render resources.
19+
render = [
20+
"mesh",
21+
"image",
22+
]
23+
# Enables support for tracking `Mesh`.
24+
mesh = ["bevy_render"]
25+
# Enables support for tracking `Image`.
26+
image = ["bevy_render"]
27+
28+
# Features required to run all the examples
29+
examples = [
30+
"bevy_render_all",
31+
"bevy_png",
32+
"bevy_winit",
33+
]
34+
35+
# Forwarded bevy features
36+
bevy_pbr = ["bevy/bevy_pbr"]
37+
bevy_png = ["bevy/png"]
38+
bevy_render_all = ["bevy/render"]
39+
bevy_render = ["bevy/bevy_render"]
40+
bevy_winit = ["bevy/bevy_winit"]
41+
42+
[[example]]
43+
name = "custom_types"
44+
45+
[[example]]
46+
name = "render_resources"
47+
required-features = [
48+
"bevy_render_all",
49+
"bevy_png",
50+
"bevy_winit"
51+
]

README.md

+42-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,42 @@ See the [`datasize`] docs for more info on that.
2020
Rustdocs for the main branch can be found
2121
[here](https://bgr360.github.io/bevy_datasize/bevy_datasize/)
2222

23-
## Example
23+
## Examples
24+
25+
### Basic Usage
26+
27+
The following example demonstrates how to show the memory usage of all loaded
28+
`Image`s:
29+
30+
```rust,no_run
31+
use bevy::prelude::*;
32+
use bevy_datasize::prelude::*;
33+
34+
fn main() {
35+
App::new()
36+
.add_plugins(DefaultPlugins)
37+
.add_plugin(DefaultMemoryUsagePlugins)
38+
.add_system(print_image_usage)
39+
.run();
40+
}
41+
42+
fn print_image_usage(memory_usage: Res<MemoryUsage>) {
43+
let MemoryStats {
44+
count,
45+
total_stack_bytes,
46+
total_heap_bytes,
47+
} = memory_usage.get_stats::<Image>().unwrap();
48+
49+
println!("Image count: {count}");
50+
println!("Total stack usage: {total_stack_bytes} bytes");
51+
println!("Total heap usage: {total_heap_bytes} bytes");
52+
}
53+
```
54+
55+
### Custom Data Types
56+
57+
The following example demonstrates how to track memory usage for a custom
58+
`Component` type when using minimal plugins:
2459

2560
```rust,no_run
2661
use bevy::prelude::*;
@@ -36,11 +71,11 @@ fn main() {
3671
.add_plugins(MinimalPlugins)
3772
.add_plugin(MemoryUsagePlugin)
3873
.register_sized_component::<MyComponent>()
39-
.add_system(print_datasize)
74+
.add_system(print_custom_usage)
4075
.run();
4176
}
4277
43-
fn print_datasize(memory_usage: Res<MemoryUsage>) {
78+
fn print_custom_usage(memory_usage: Res<MemoryUsage>) {
4479
let MemoryStats {
4580
count,
4681
total_stack_bytes,
@@ -53,6 +88,10 @@ fn print_datasize(memory_usage: Res<MemoryUsage>) {
5388
}
5489
```
5590

91+
### More
92+
93+
See the [`examples`](examples/) directory for more examples.
94+
5695
## License
5796

5897
Licensed under either of

assets/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Assets
2+
3+
These are just used for the examples.
4+
5+
## Attribution
6+
7+
### [`grass_0_0.png`](grass_0_0.png)
8+
9+
Title: "Grass 001"
10+
11+
Description: 512x512 seamless grass texture, made using CC-BY 3.0 photos from
12+
the Yo Frankie! DVD.
13+
14+
Link: https://opengameart.org/node/7806
15+
16+
No changes were made.
17+
18+
(c) copyright Blender Foundation | apricot.blender.org

assets/grass_0_0.png

164 KB
Loading

examples/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# bevy_datasize examples
2+
3+
To run the examples, you must enable the `examples` feature:
4+
5+
```
6+
$ cargo run --features examples --example <EXAMPLE>
7+
```
File renamed without changes.

examples/render_resources.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//! This example shows demonstrates tracking memory usage for render resources
2+
//! like meshes, images, and materials.
3+
//!
4+
//! Adapted from the official Bevy `many_cubes` example.
5+
6+
use bevy::prelude::*;
7+
use bevy_datasize::prelude::*;
8+
9+
fn main() {
10+
App::new()
11+
.add_plugins(DefaultPlugins)
12+
.add_plugins(DefaultMemoryUsagePlugins)
13+
.add_startup_system(setup)
14+
.add_system(print_sizes)
15+
.run();
16+
}
17+
18+
fn setup(
19+
asset_server: Res<AssetServer>,
20+
mut commands: Commands,
21+
mut meshes: ResMut<Assets<Mesh>>,
22+
mut materials: ResMut<Assets<StandardMaterial>>,
23+
) {
24+
const WIDTH: usize = 10;
25+
const HEIGHT: usize = 10;
26+
let texture = asset_server.load("grass_0_0.png");
27+
let material = materials.add(StandardMaterial {
28+
base_color_texture: Some(texture),
29+
..Default::default()
30+
});
31+
for x in 0..WIDTH {
32+
for y in 0..HEIGHT {
33+
// cube
34+
commands.spawn_bundle(PbrBundle {
35+
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
36+
material: material.clone(),
37+
transform: Transform::from_xyz((x as f32) * 2.0, (y as f32) * 2.0, 0.0),
38+
..Default::default()
39+
});
40+
}
41+
}
42+
43+
// camera
44+
commands.spawn_bundle(PerspectiveCameraBundle {
45+
transform: Transform::from_xyz(80.0, 80.0, 300.0),
46+
..Default::default()
47+
});
48+
}
49+
50+
fn print_sizes(memory_usage: Res<MemoryUsage>) {
51+
let mesh_stats = memory_usage.get_stats::<Mesh>().unwrap();
52+
let image_stats = memory_usage.get_stats::<Image>().unwrap();
53+
54+
println!();
55+
println!("Memory usage:");
56+
println!("Meshes: {:#?}", mesh_stats);
57+
println!("Images: {:#?}", image_stats);
58+
}

src/app_ext.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use bevy::{
66
ecs::{component::Component, schedule::IntoSystemDescriptor, system::Resource},
77
};
88

9-
use crate::{systems, DataSize, DataSizeEstimator, MemoryUsage};
9+
use crate::{estimator::ForwardingEstimator, systems, DataSize, MemoryUsage};
1010

1111
/// [`App`] extension methods to register types for memory usage tracking.
1212
pub trait RegisterSizedTypes {
@@ -19,7 +19,9 @@ pub trait RegisterSizedTypes {
1919
where
2020
T: Any + DataSize + Component,
2121
{
22-
self.register_sized_type::<T, T, _, _>(systems::update_stats_for_component::<T, T>)
22+
self.register_sized_type::<T, _, _>(
23+
systems::update_stats_for_component::<T, ForwardingEstimator<T>>,
24+
)
2325
}
2426

2527
/// Registers the given [`Resource`] type with the
@@ -31,7 +33,9 @@ pub trait RegisterSizedTypes {
3133
where
3234
T: Any + DataSize + Resource,
3335
{
34-
self.register_sized_type::<T, T, _, _>(systems::update_stats_for_resource::<T, T>)
36+
self.register_sized_type::<T, _, _>(
37+
systems::update_stats_for_resource::<T, ForwardingEstimator<T>>,
38+
)
3539
}
3640

3741
/// Registers the given [`Asset`] type with the
@@ -43,23 +47,28 @@ pub trait RegisterSizedTypes {
4347
where
4448
T: Any + DataSize + Asset,
4549
{
46-
self.register_sized_type::<T, T, _, _>(systems::update_stats_for_asset::<T, T>)
50+
self.register_sized_type::<T, _, _>(
51+
systems::update_stats_for_asset::<T, ForwardingEstimator<T>>,
52+
)
4753
}
4854

49-
/// Registers a type that can be sized with the given [`DataSizeEstimator`]
50-
/// type and updated using the provided `system`.
51-
fn register_sized_type<T, E, S, Params>(&mut self, system: S) -> &mut Self
55+
/// Registers a type whose [`MemoryStats`] will be updated with the given
56+
/// `system`.
57+
///
58+
/// The given type `T` will be available to query on the [`MemoryUsage`]
59+
/// resource.
60+
///
61+
/// [`MemoryStats`]: crate::MemoryStats
62+
fn register_sized_type<T, S, Params>(&mut self, system: S) -> &mut Self
5263
where
5364
T: Any,
54-
E: DataSizeEstimator<T>,
5565
S: IntoSystemDescriptor<Params>;
5666
}
5767

5868
impl RegisterSizedTypes for App {
59-
fn register_sized_type<T, E, S, Params>(&mut self, system: S) -> &mut Self
69+
fn register_sized_type<T, S, Params>(&mut self, system: S) -> &mut Self
6070
where
6171
T: Any,
62-
E: DataSizeEstimator<T>,
6372
S: IntoSystemDescriptor<Params>,
6473
{
6574
register_type::<T>(self);

src/builtins/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//! Support for Bevy's built-in types.
2+
3+
use bevy::app::{PluginGroup, PluginGroupBuilder};
4+
5+
use crate::MemoryUsagePlugin;
6+
7+
pub mod render;
8+
9+
pub use render::RenderMemoryUsagePlugins;
10+
11+
/// Adds memory tracking for the components, resources, and assets that are part
12+
/// of Bevy's [`DefaultPlugins`][bevy::prelude::DefaultPlugins].
13+
///
14+
/// This group registers the [`MemoryUsagePlugin`] as well as the following:
15+
///
16+
/// * [`RenderMemoryUsagePlugins`]
17+
pub struct DefaultMemoryUsagePlugins;
18+
19+
impl PluginGroup for DefaultMemoryUsagePlugins {
20+
fn build(&mut self, group: &mut PluginGroupBuilder) {
21+
group.add(MemoryUsagePlugin);
22+
23+
RenderMemoryUsagePlugins.build(group);
24+
}
25+
}

src/builtins/render/image.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! Memory usage tracking for Bevy's [`Image`] type.
2+
use bevy::{app::Plugin, render::texture::Image};
3+
4+
use crate::{systems, DataSize, DataSizeEstimator, RegisterSizedTypes};
5+
6+
/// Adds memory tracking for [`Image`] assets.
7+
#[derive(Debug, Default)]
8+
pub struct ImageMemoryUsagePlugin;
9+
10+
impl Plugin for ImageMemoryUsagePlugin {
11+
fn build(&self, app: &mut bevy::prelude::App) {
12+
app.register_sized_type::<Image, _, _>(
13+
systems::update_stats_for_asset::<Image, ImageSizeEstimator>,
14+
);
15+
}
16+
}
17+
18+
#[derive(Debug, Default)]
19+
struct ImageSizeEstimator;
20+
21+
impl DataSizeEstimator<Image> for ImageSizeEstimator {
22+
/// Returns the size of the image's data array.
23+
#[inline]
24+
fn estimate_heap_size(&self, image: &Image) -> usize {
25+
image.data.estimate_heap_size()
26+
}
27+
}

0 commit comments

Comments
 (0)