bevy_render/diagnostic/
erased_render_asset_diagnostic_plugin.rs1use core::{any::type_name, marker::PhantomData};
2
3use bevy_app::{Plugin, PreUpdate};
4use bevy_diagnostic::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic};
5use bevy_ecs::{resource::Resource, system::Res};
6use bevy_platform::sync::atomic::{AtomicUsize, Ordering};
7
8use crate::{
9 erased_render_asset::{ErasedRenderAsset, ErasedRenderAssets},
10 Extract, ExtractSchedule, RenderApp,
11};
12
13pub struct ErasedRenderAssetDiagnosticPlugin<A: ErasedRenderAsset> {
18 suffix: &'static str,
19 _phantom: PhantomData<A>,
20}
21
22impl<A: ErasedRenderAsset> ErasedRenderAssetDiagnosticPlugin<A> {
23 pub fn new(suffix: &'static str) -> Self {
24 Self {
25 suffix,
26 _phantom: PhantomData,
27 }
28 }
29
30 pub fn render_asset_diagnostic_path() -> DiagnosticPath {
31 DiagnosticPath::from_components(["erased_render_asset", type_name::<A>()])
32 }
33}
34
35impl<A: ErasedRenderAsset> Plugin for ErasedRenderAssetDiagnosticPlugin<A> {
36 fn build(&self, app: &mut bevy_app::App) {
37 app.register_diagnostic(
38 Diagnostic::new(Self::render_asset_diagnostic_path()).with_suffix(self.suffix),
39 )
40 .init_resource::<ErasedRenderAssetMeasurements<A>>()
41 .add_systems(PreUpdate, add_erased_render_asset_measurement::<A>);
42
43 if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
44 render_app.add_systems(ExtractSchedule, measure_erased_render_asset::<A>);
45 }
46 }
47}
48
49#[derive(Debug, Resource)]
50struct ErasedRenderAssetMeasurements<A: ErasedRenderAsset> {
51 assets: AtomicUsize,
52 _phantom: PhantomData<A>,
53}
54
55impl<A: ErasedRenderAsset> Default for ErasedRenderAssetMeasurements<A> {
56 fn default() -> Self {
57 Self {
58 assets: AtomicUsize::default(),
59 _phantom: PhantomData,
60 }
61 }
62}
63
64fn add_erased_render_asset_measurement<A: ErasedRenderAsset>(
65 mut diagnostics: Diagnostics,
66 measurements: Res<ErasedRenderAssetMeasurements<A>>,
67) {
68 diagnostics.add_measurement(
69 &ErasedRenderAssetDiagnosticPlugin::<A>::render_asset_diagnostic_path(),
70 || measurements.assets.load(Ordering::Relaxed) as f64,
71 );
72}
73
74fn measure_erased_render_asset<A: ErasedRenderAsset>(
75 measurements: Extract<Res<ErasedRenderAssetMeasurements<A>>>,
76 assets: Res<ErasedRenderAssets<A::ErasedAsset>>,
77) {
78 measurements
79 .assets
80 .store(assets.iter().count(), Ordering::Relaxed);
81}