1
+ //! Extension traits for [`App`].
2
+
1
3
use std:: any:: Any ;
2
4
3
5
use bevy:: {
4
6
app:: App ,
5
7
asset:: Asset ,
6
- ecs:: { component:: Component , schedule:: IntoSystemDescriptor , system:: Resource } ,
8
+ ecs:: {
9
+ component:: Component , schedule:: IntoSystemDescriptor , schedule:: StageLabel ,
10
+ system:: Resource ,
11
+ } ,
12
+ prelude:: CoreStage ,
7
13
} ;
8
14
9
- use crate :: { estimator:: ForwardingEstimator , systems, DataSize , MemoryUsage } ;
15
+ #[ cfg( feature = "bevy_render" ) ]
16
+ use bevy:: render:: { render_asset:: RenderAsset , RenderApp , RenderStage } ;
17
+
18
+ use crate :: {
19
+ estimator:: { ForwardingEstimator , FromConfig } ,
20
+ systems, DataSize , DataSizeEstimator , MemoryUsage ,
21
+ } ;
10
22
11
- /// [`App`] extension methods to register types for memory usage tracking.
12
- pub trait RegisterSizedTypes {
23
+ /// [`App`] extension methods to register [`DataSize`] types for memory usage
24
+ /// tracking.
25
+ ///
26
+ /// For types that do not implement [`DataSize`], you will need to implement a
27
+ /// [`DataSizeEstimator`] for them and register them using the methods in
28
+ /// [`RegisterTypesWithEstimator`].
29
+ pub trait RegisterSizedTypes : RegisterTypesWithEstimator {
13
30
/// Registers the given [`Component`] type with the
14
31
/// [`MemoryUsagePlugin`][crate::MemoryUsagePlugin].
15
32
///
@@ -19,9 +36,7 @@ pub trait RegisterSizedTypes {
19
36
where
20
37
T : Any + DataSize + Component ,
21
38
{
22
- self . register_sized_type :: < T , _ , _ > (
23
- systems:: update_stats_for_component :: < T , ForwardingEstimator > ,
24
- )
39
+ self . register_component_with_estimator :: < T , ForwardingEstimator > ( )
25
40
}
26
41
27
42
/// Registers the given [`Resource`] type with the
@@ -33,9 +48,7 @@ pub trait RegisterSizedTypes {
33
48
where
34
49
T : Any + DataSize + Resource ,
35
50
{
36
- self . register_sized_type :: < T , _ , _ > (
37
- systems:: update_stats_for_resource :: < T , ForwardingEstimator > ,
38
- )
51
+ self . register_resource_with_estimator :: < T , ForwardingEstimator > ( )
39
52
}
40
53
41
54
/// Registers the given [`Asset`] type with the
@@ -47,39 +60,145 @@ pub trait RegisterSizedTypes {
47
60
where
48
61
T : Any + DataSize + Asset ,
49
62
{
50
- self . register_sized_type :: < T , _ , _ > (
51
- systems:: update_stats_for_asset :: < T , ForwardingEstimator > ,
63
+ self . register_asset_with_estimator :: < T , ForwardingEstimator > ( )
64
+ }
65
+
66
+ /// Registers the given [`Asset`] type with the
67
+ /// [`MemoryUsagePlugin`][crate::MemoryUsagePlugin].
68
+ ///
69
+ /// The following types will be available to query on the [`MemoryUsage`]
70
+ /// resource:
71
+ ///
72
+ /// * `T`
73
+ /// * `<T as RenderAsset>::ExtractedAsset`
74
+ /// * `<T as RenderAsset>::PreparedAsset`
75
+ #[ cfg( feature = "bevy_render" ) ]
76
+ fn register_sized_render_asset < T > ( & mut self ) -> & mut Self
77
+ where
78
+ T : Any + DataSize + RenderAsset ,
79
+ <T as RenderAsset >:: PreparedAsset : Any + DataSize ,
80
+ {
81
+ self . register_render_asset_with_estimator :: < T , ForwardingEstimator , ForwardingEstimator > ( )
82
+ }
83
+ }
84
+
85
+ impl RegisterSizedTypes for App { }
86
+
87
+ /// [`App`] extension methods to register non-[`DataSize`] types for memory
88
+ /// usage tracking.
89
+ pub trait RegisterTypesWithEstimator : RegisterTypes {
90
+ /// Like [`RegisterSizedTypes::register_sized_component`], but uses the
91
+ /// given [`DataSizeEstimator`] type.
92
+ fn register_component_with_estimator < T , E > ( & mut self ) -> & mut Self
93
+ where
94
+ T : Any + Component ,
95
+ E : DataSizeEstimator < T > + FromConfig + ' static ,
96
+ {
97
+ self . register_type :: < T , _ , _ , _ > (
98
+ systems:: update_stats_for_component :: < T , E > ,
99
+ CoreStage :: Update ,
52
100
)
53
101
}
54
102
103
+ /// Like [`RegisterSizedTypes::register_sized_resource`], but uses the
104
+ /// given [`DataSizeEstimator`] type.
105
+ fn register_resource_with_estimator < T , E > ( & mut self ) -> & mut Self
106
+ where
107
+ T : Any + Resource ,
108
+ E : DataSizeEstimator < T > + FromConfig + ' static ,
109
+ {
110
+ self . register_type :: < T , _ , _ , _ > (
111
+ systems:: update_stats_for_resource :: < T , E > ,
112
+ CoreStage :: Update ,
113
+ )
114
+ }
115
+
116
+ /// Like [`RegisterSizedTypes::register_sized_asset`], but uses the
117
+ /// given [`DataSizeEstimator`] type.
118
+ fn register_asset_with_estimator < T , E > ( & mut self ) -> & mut Self
119
+ where
120
+ T : Any + Asset ,
121
+ E : DataSizeEstimator < T > + FromConfig + ' static ,
122
+ {
123
+ self . register_type :: < T , _ , _ , _ > ( systems:: update_stats_for_asset :: < T , E > , CoreStage :: Update )
124
+ }
125
+
126
+ /// Like [`RegisterSizedTypes::register_sized_asset`], but uses the given
127
+ /// [`DataSizeEstimator`] types to estimate the size of the [`RenderAsset`]
128
+ /// and its prepared format.
129
+ #[ cfg( feature = "bevy_render" ) ]
130
+ fn register_render_asset_with_estimator < T , E , F > ( & mut self ) -> & mut Self
131
+ where
132
+ T : Any + RenderAsset ,
133
+ E : DataSizeEstimator < T > + FromConfig + ' static ,
134
+ <T as RenderAsset >:: PreparedAsset : Any ,
135
+ F : DataSizeEstimator < <T as RenderAsset >:: PreparedAsset > + FromConfig + ' static ;
136
+ }
137
+
138
+ impl RegisterTypesWithEstimator for App {
139
+ #[ cfg( feature = "bevy_render" ) ]
140
+ fn register_render_asset_with_estimator < T , E , F > ( & mut self ) -> & mut Self
141
+ where
142
+ T : Any + RenderAsset ,
143
+ E : DataSizeEstimator < T > + FromConfig + ' static ,
144
+ <T as RenderAsset >:: PreparedAsset : Any ,
145
+ F : DataSizeEstimator < <T as RenderAsset >:: PreparedAsset > + FromConfig + ' static ,
146
+ {
147
+ RegisterTypes :: register_type :: < T , _ , _ , _ > (
148
+ self ,
149
+ systems:: update_stats_for_asset :: < T , E > ,
150
+ CoreStage :: Update ,
151
+ ) ;
152
+
153
+ if let Ok ( render_app) = self . get_sub_app_mut ( RenderApp ) {
154
+ RegisterTypes :: register_type :: < <T as RenderAsset >:: PreparedAsset , _ , _ , _ > (
155
+ render_app,
156
+ systems:: update_stats_for_render_asset :: < T , F > ,
157
+ // TODO: find the appropriate stage for this.
158
+ RenderStage :: Render ,
159
+ ) ;
160
+
161
+ // Also register the type on the main app so there are entries for
162
+ // it in the hashmap.
163
+ register_type_on_app :: < T > ( self ) ;
164
+ }
165
+
166
+ self
167
+ }
168
+ }
169
+
170
+ /// The lowest-level interface for registering types for memory usage tracking.
171
+ pub trait RegisterTypes {
55
172
/// Registers a type whose [`MemoryStats`] will be updated with the given
56
- /// `system`.
173
+ /// `system`, which will run in the given `stage` .
57
174
///
58
175
/// The given type `T` will be available to query on the [`MemoryUsage`]
59
176
/// resource.
60
177
///
61
178
/// [`MemoryStats`]: crate::MemoryStats
62
- fn register_sized_type < T , S , Params > ( & mut self , system : S ) -> & mut Self
179
+ fn register_type < T , S , Params , L > ( & mut self , system : S , stage : L ) -> & mut Self
63
180
where
64
181
T : Any ,
65
- S : IntoSystemDescriptor < Params > ;
182
+ S : IntoSystemDescriptor < Params > ,
183
+ L : StageLabel ;
66
184
}
67
185
68
- impl RegisterSizedTypes for App {
69
- fn register_sized_type < T , S , Params > ( & mut self , system : S ) -> & mut Self
186
+ impl RegisterTypes for App {
187
+ fn register_type < T , S , Params , L > ( & mut self , system : S , stage : L ) -> & mut Self
70
188
where
71
189
T : Any ,
72
190
S : IntoSystemDescriptor < Params > ,
191
+ L : StageLabel ,
73
192
{
74
- register_type :: < T > ( self ) ;
193
+ register_type_on_app :: < T > ( self ) ;
75
194
76
- self . add_system ( system) ;
195
+ self . add_system_to_stage ( stage , system) ;
77
196
78
197
self
79
198
}
80
199
}
81
200
82
- fn register_type < T > ( app : & mut App )
201
+ fn register_type_on_app < T > ( app : & mut App )
83
202
where
84
203
T : Any ,
85
204
{
0 commit comments