Skip to main content

rig_ecs/systems/
diagnostics.rs

1//! Runtime effect and run counts exposed as Bevy diagnostic time series.
2//!
3//! ```
4//! let mut app = bevy_app::App::new();
5//! app.add_plugins(bevy_diagnostic::DiagnosticsPlugin);
6//! rig_ecs::systems::diagnostics::register(&mut app);
7//! ```
8
9use bevy_app::App;
10use bevy_diagnostic::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic};
11use bevy_ecs::{prelude::*, query::QueryFilter};
12
13use crate::{
14    agent::{Failed, Run, Settled},
15    bus::{InFlight, PendingEffect},
16};
17
18/// Effects in flight at the end of the pass.
19pub const EFFECTS_IN_FLIGHT: DiagnosticPath = DiagnosticPath::const_new("rig/effects/in_flight");
20/// Effects pending dispatch at the end of the pass.
21pub const EFFECTS_PENDING: DiagnosticPath = DiagnosticPath::const_new("rig/effects/pending");
22/// Runs neither settled nor failed.
23pub const RUNS_LIVE: DiagnosticPath = DiagnosticPath::const_new("rig/runs/live");
24
25/// Register every diagnostic.
26pub fn register(app: &mut App) {
27    app.register_diagnostic(Diagnostic::new(EFFECTS_IN_FLIGHT))
28        .register_diagnostic(Diagnostic::new(EFFECTS_PENDING))
29        .register_diagnostic(Diagnostic::new(RUNS_LIVE));
30}
31
32/// An effect pending dispatch.
33#[derive(QueryFilter)]
34pub struct PendingDispatch {
35    _pending: With<PendingEffect>,
36    _not_taken: Without<InFlight>,
37    _not_answered: Without<crate::bus::EffectOutcome>,
38}
39
40/// A run neither settled nor failed.
41#[derive(QueryFilter)]
42pub struct LiveRun {
43    _run: With<Run>,
44    _not_settled: Without<Settled>,
45    _not_failed: Without<Failed>,
46}
47
48/// `RigSet::Settle`: one measurement per diagnostic per pass.
49pub fn measure(
50    mut diagnostics: Diagnostics,
51    in_flight: Query<(), With<InFlight>>,
52    pending: Query<(), PendingDispatch>,
53    live: Query<(), LiveRun>,
54) {
55    diagnostics.add_measurement(&EFFECTS_IN_FLIGHT, || in_flight.iter().count() as f64);
56    diagnostics.add_measurement(&EFFECTS_PENDING, || pending.iter().count() as f64);
57    diagnostics.add_measurement(&RUNS_LIVE, || live.iter().count() as f64);
58}