1
1
//! An allocator used to control the lifetime of allocations
2
2
3
- use bevy:: { ecs:: system:: Resource , prelude:: ResMut , reflect:: PartialReflect } ;
3
+ use bevy:: {
4
+ app:: { App , Plugin , PostUpdate } ,
5
+ diagnostic:: { Diagnostic , DiagnosticPath , Diagnostics , RegisterDiagnostic } ,
6
+ ecs:: system:: { Res , Resource } ,
7
+ prelude:: ResMut ,
8
+ reflect:: PartialReflect ,
9
+ } ;
4
10
use parking_lot:: { RwLock , RwLockReadGuard , RwLockWriteGuard } ;
5
11
use std:: {
6
12
cell:: UnsafeCell ,
@@ -11,6 +17,14 @@ use std::{
11
17
sync:: { atomic:: AtomicU64 , Arc } ,
12
18
} ;
13
19
20
+ /// The path used for the total number of allocations diagnostic
21
+ pub const ALLOCATOR_TOTAL_DIAG_PATH : DiagnosticPath =
22
+ DiagnosticPath :: const_new ( "scripting_allocator_total" ) ;
23
+
24
+ /// The path used for the total number of deallocated allocations diagnostic
25
+ pub const ALLOCATOR_TOTAL_COLLECTED_DIAG_PATH : DiagnosticPath =
26
+ DiagnosticPath :: const_new ( "scripting_allocator_total_collected" ) ;
27
+
14
28
#[ derive( Clone , Debug ) ]
15
29
/// Unique identifier for an allocation
16
30
pub struct ReflectAllocationId ( pub ( crate ) Arc < u64 > ) ;
@@ -214,9 +228,34 @@ impl ReflectAllocator {
214
228
215
229
/// Cleans up dangling script allocations
216
230
#[ profiling:: function]
217
- pub fn garbage_collector ( allocator : ResMut < AppReflectAllocator > ) {
231
+ pub fn garbage_collector ( allocator : ResMut < AppReflectAllocator > , mut diagnostics : Diagnostics ) {
218
232
let mut allocator = allocator. write ( ) ;
219
- allocator. clean_garbage_allocations ( )
233
+ let before = allocator. allocations . len ( ) ;
234
+ allocator. clean_garbage_allocations ( ) ;
235
+ let after = allocator. allocations . len ( ) ;
236
+ diagnostics. add_measurement ( & ALLOCATOR_TOTAL_DIAG_PATH , || after as f64 ) ;
237
+ diagnostics. add_measurement ( & ALLOCATOR_TOTAL_COLLECTED_DIAG_PATH , || {
238
+ ( before - after) as f64
239
+ } ) ;
240
+ }
241
+
242
+ /// Measures the number of allocations in the allocator and other diagnostics when enabled
243
+ pub fn measure_allocations ( allocator : Res < AppReflectAllocator > , mut diagnostics : Diagnostics ) {
244
+ let allocator = allocator. read ( ) ;
245
+ let allocations_count = allocator. allocations . len ( ) ;
246
+ diagnostics. add_measurement ( & ALLOCATOR_TOTAL_DIAG_PATH , || allocations_count as f64 ) ;
247
+ }
248
+
249
+ /// A plugin which registers various allocator diagnostics
250
+ pub struct AllocatorDiagnosticPlugin ;
251
+ impl Plugin for AllocatorDiagnosticPlugin {
252
+ fn build ( & self , app : & mut App ) {
253
+ app. register_diagnostic ( Diagnostic :: new ( ALLOCATOR_TOTAL_DIAG_PATH ) . with_suffix ( " allocs" ) )
254
+ . register_diagnostic (
255
+ Diagnostic :: new ( ALLOCATOR_TOTAL_COLLECTED_DIAG_PATH ) . with_suffix ( " deallocs" ) ,
256
+ )
257
+ . add_systems ( PostUpdate , measure_allocations) ;
258
+ }
220
259
}
221
260
222
261
#[ cfg( test) ]
0 commit comments