Skip to content

Commit c8c6899

Browse files
committed
Add support for resources and assets, and boof up docs.
1 parent 2d448c3 commit c8c6899

File tree

5 files changed

+213
-44
lines changed

5 files changed

+213
-44
lines changed

examples/basic.rs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//! This example shows how to register your own resource, component, and asset
2+
//! types for memory usage tracking.
3+
4+
use bevy::{prelude::*, reflect::TypeUuid};
5+
use bevy_datasize::prelude::*;
6+
7+
#[derive(DataSize)]
8+
struct MyResource {
9+
pub data: Vec<u8>,
10+
}
11+
12+
#[derive(Component, DataSize)]
13+
struct MyComponent {
14+
pub data: Vec<u8>,
15+
}
16+
17+
#[derive(Debug, TypeUuid)]
18+
#[uuid = "0669d1a3-34b5-4bac-b9cd-26a2e2df79ff"]
19+
pub struct MyAsset {
20+
pub data: Vec<u8>,
21+
}
22+
23+
fn main() {
24+
App::new()
25+
.add_plugins(MinimalPlugins)
26+
.add_plugin(MemoryUsagePlugin)
27+
.register_sized_resource::<MyResource>()
28+
.register_sized_component::<MyComponent>()
29+
.insert_resource(MyResource {
30+
data: vec![42; 4096],
31+
})
32+
.add_startup_system(spawn_entities)
33+
.add_startup_system(add_asset)
34+
.add_system(print_sizes)
35+
.run();
36+
}
37+
38+
fn spawn_entities(mut commands: Commands) {
39+
for _ in 0..8 {
40+
let component = MyComponent {
41+
data: vec![0; 1024],
42+
};
43+
commands.spawn().insert(component);
44+
}
45+
}
46+
47+
fn add_asset(mut handle: Local<Handle<MyAsset>>, mut assets: ResMut<Assets<MyAsset>>) {
48+
*handle = assets.add(MyAsset {
49+
data: vec![68; 425],
50+
});
51+
}
52+
53+
fn print_sizes(memory_usage: Res<MemoryUsage>) {
54+
let resource_stats = memory_usage.get_stats::<MyResource>().unwrap();
55+
let component_stats = memory_usage.get_stats::<MyComponent>().unwrap();
56+
let asset_stats = memory_usage.get_stats::<MyAsset>().unwrap();
57+
58+
println!();
59+
println!("Memory usage:");
60+
println!("MyResource: {:#?}", resource_stats);
61+
println!("MyComponent: {:#?}", component_stats);
62+
println!("MyAsset: {:#?}", asset_stats);
63+
}

examples/components.rs

-31
This file was deleted.

src/app_ext.rs

+59-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use std::any::Any;
22

3-
use bevy::app::App;
4-
use bevy::ecs::component::Component;
3+
use bevy::{
4+
app::App,
5+
asset::Asset,
6+
ecs::{component::Component, system::Resource},
7+
};
58

6-
use crate::{systems::update_stats_for_component, DataSize, MemoryUsage};
9+
use crate::{systems, DataSize, MemoryUsage};
710

811
/// [`App`] extension methods to register types for memory usage tracking.
912
pub trait RegisterSizedTypes {
@@ -14,22 +17,69 @@ pub trait RegisterSizedTypes {
1417
/// resource.
1518
fn register_sized_component<T>(&mut self) -> &mut Self
1619
where
17-
T: Any + Component + DataSize;
20+
T: Any + DataSize + Component;
21+
22+
/// Registers the given [`Resource`] type with the
23+
/// [`MemoryUsagePlugin`][crate::MemoryUsagePlugin].
24+
///
25+
/// The given type `T` will be available to query on the [`MemoryUsage`]
26+
/// resource.
27+
fn register_sized_resource<T>(&mut self) -> &mut Self
28+
where
29+
T: Any + DataSize + Resource;
30+
31+
/// Registers the given [`Asset`] type with the
32+
/// [`MemoryUsagePlugin`][crate::MemoryUsagePlugin].
33+
///
34+
/// The given type `T` will be available to query on the [`MemoryUsage`]
35+
/// resource.
36+
fn register_sized_asset<T>(&mut self) -> &mut Self
37+
where
38+
T: Any + DataSize + Asset;
1839
}
1940

2041
impl RegisterSizedTypes for App {
2142
fn register_sized_component<T>(&mut self) -> &mut Self
2243
where
2344
T: Any + Component + DataSize,
2445
{
25-
let mut memory_usage = self.world.get_resource_mut::<MemoryUsage>().expect(
26-
"Cannot find resource `MemoryUsage`. Did you forget to add the `MemoryUsagePlugin`?",
27-
);
46+
register_type::<T>(self);
47+
48+
self.add_system(systems::update_stats_for_component::<T>);
49+
50+
self
51+
}
52+
53+
fn register_sized_resource<T>(&mut self) -> &mut Self
54+
where
55+
T: Any + DataSize + Resource,
56+
{
57+
register_type::<T>(self);
58+
59+
self.add_system(systems::update_stats_for_resource::<T>);
60+
61+
self
62+
}
2863

29-
memory_usage.register_type::<T>();
64+
fn register_sized_asset<T>(&mut self) -> &mut Self
65+
where
66+
T: Any + DataSize + Asset,
67+
{
68+
register_type::<T>(self);
3069

31-
self.add_system(update_stats_for_component::<T>);
70+
self.add_system(systems::update_stats_for_asset::<T>);
3271

3372
self
3473
}
3574
}
75+
76+
fn register_type<T>(app: &mut App)
77+
where
78+
T: Any + DataSize,
79+
{
80+
let mut memory_usage = app.world.get_resource_mut::<MemoryUsage>().expect(
81+
"Cannot find resource `MemoryUsage`. Did you forget to add the `MemoryUsagePlugin`?",
82+
);
83+
84+
memory_usage.register_type::<T>();
85+
}

src/lib.rs

+47-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,42 @@
1-
#![doc = include_str!("../README.md")]
1+
//! This is a library for tracking memory usage in [Bevy](https://lib.rs/bevy) apps.
2+
//!
3+
//! It is based on the [`datasize`] crate.
4+
//!
5+
//! # Example
6+
//!
7+
//! ```no_run
8+
//! use bevy::prelude::*;
9+
//! use bevy_datasize::prelude::*;
10+
//!
11+
//! #[derive(Component, DataSize)]
12+
//! struct MyComponent {
13+
//! data: Vec<u8>,
14+
//! }
15+
//!
16+
//! fn main() {
17+
//! App::new()
18+
//! .add_plugins(MinimalPlugins)
19+
//! .add_plugin(MemoryUsagePlugin)
20+
//! .register_sized_component::<MyComponent>()
21+
//! .add_system(print_datasize)
22+
//! .run();
23+
//! }
24+
//!
25+
//! fn print_datasize(memory_usage: Res<MemoryUsage>) {
26+
//! let MemoryStats {
27+
//! count,
28+
//! total_stack_bytes,
29+
//! total_heap_bytes,
30+
//! } = memory_usage.get_stats::<MyComponent>().unwrap();
31+
//!
32+
//! println!("MyComponent count: {count}");
33+
//! println!("MyComponent total stack usage: {total_stack_bytes} bytes");
34+
//! println!("MyComponent total heap usage: {total_heap_bytes} bytes");
35+
//! }
36+
//! ```
37+
//!
38+
//! See the [`datasize`] docs for more information on the [`DataSize`] trait.
39+
240
#![warn(missing_docs)]
341

442
pub use datasize::DataSize;
@@ -18,5 +56,12 @@ pub use stats::MemoryStats;
1856

1957
#[allow(missing_docs)]
2058
pub mod prelude {
21-
pub use crate::{MemoryConfig, MemoryUsage, MemoryUsagePlugin, RegisterSizedTypes};
59+
pub use crate::{
60+
DataSize, MemoryConfig, MemoryStats, MemoryUsage, MemoryUsagePlugin, RegisterSizedTypes,
61+
};
2262
}
63+
64+
// Make sure the README example compiles
65+
#[cfg(doctest)]
66+
#[doc = include_str!("../README.md")]
67+
pub struct ReadmeTest;

src/systems.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
33
use std::any::Any;
44

5-
use bevy::prelude::*;
5+
use bevy::{
6+
asset::{Asset, Assets},
7+
ecs::{
8+
component::Component,
9+
system::{Query, Res, Resource},
10+
},
11+
};
612
use datasize::DataSize;
713

814
use crate::{MemoryConfig, MemoryStats, MemoryUsage};
@@ -15,12 +21,48 @@ pub fn update_stats_for_component<T>(
1521
memory_usage: Res<MemoryUsage>,
1622
) where
1723
T: Any + Component + DataSize,
24+
{
25+
update_stats::<T, _>(memory_config, memory_usage, || {
26+
MemoryStats::from_values(query.iter())
27+
});
28+
}
29+
30+
/// This system updates the [`MemoryStats`] for the given resource type `T`.
31+
pub fn update_stats_for_resource<T>(
32+
resource: Res<T>,
33+
memory_config: Res<MemoryConfig>,
34+
memory_usage: Res<MemoryUsage>,
35+
) where
36+
T: Any + DataSize + Resource,
37+
{
38+
update_stats::<T, _>(memory_config, memory_usage, || {
39+
MemoryStats::from_value(&*resource)
40+
});
41+
}
42+
43+
/// This system updates the [`MemoryStats`] for the given asset type `T`.
44+
pub fn update_stats_for_asset<T>(
45+
assets: Res<Assets<T>>,
46+
memory_config: Res<MemoryConfig>,
47+
memory_usage: Res<MemoryUsage>,
48+
) where
49+
T: Any + DataSize + Asset,
50+
{
51+
update_stats::<T, _>(memory_config, memory_usage, || {
52+
MemoryStats::from_values(assets.iter().map(|(_handle, asset)| asset))
53+
});
54+
}
55+
56+
fn update_stats<T, F>(memory_config: Res<MemoryConfig>, memory_usage: Res<MemoryUsage>, op: F)
57+
where
58+
T: Any + DataSize,
59+
F: FnOnce() -> MemoryStats,
1860
{
1961
if !memory_config.global {
2062
return;
2163
}
2264

23-
let stats = MemoryStats::from_values(query.iter());
65+
let stats = op();
2466

2567
memory_usage.update_stats_fast::<T>(stats);
2668
}

0 commit comments

Comments
 (0)