use std::time::Duration;
use bevy::prelude::*;
use crate::{AstrodynPlugin, IntegrationDtR};
pub trait AstrodynAppExt {
fn add_astrodyn(&mut self, dt_seconds: f64) -> &mut Self;
fn step_fixed_dt(&mut self, n: usize, dt_seconds: f64) -> &mut Self;
fn step_fixed(&mut self, n: usize) -> &mut Self;
}
impl AstrodynAppExt for App {
fn add_astrodyn(&mut self, dt_seconds: f64) -> &mut Self {
self.insert_resource(Time::<Fixed>::from_seconds(dt_seconds));
self.insert_resource(IntegrationDtR(dt_seconds));
if !self.is_plugin_added::<AstrodynPlugin>() {
self.add_plugins(AstrodynPlugin);
}
self
}
fn step_fixed_dt(&mut self, n: usize, dt_seconds: f64) -> &mut Self {
let dur = Duration::from_secs_f64(dt_seconds);
self.insert_resource(IntegrationDtR(dt_seconds));
for _ in 0..n {
self.world_mut()
.resource_mut::<Time<Fixed>>()
.advance_by(dur);
self.world_mut().run_schedule(FixedUpdate);
}
self
}
fn step_fixed(&mut self, n: usize) -> &mut Self {
let dt_seconds = self
.world()
.get_resource::<IntegrationDtR>()
.unwrap_or_else(|| {
panic!(
"AstrodynAppExt::step_fixed: `IntegrationDtR` resource is missing from \
the world. The convenience overload reads `dt` from `IntegrationDtR` \
to drive the pipeline with the bit-exact f64 it was configured for. \
Call `app.add_astrodyn(dt_seconds)` first (which installs both \
`Time<Fixed>` and `IntegrationDtR` then adds `AstrodynPlugin`), or \
use `step_fixed_dt(n, dt_seconds)` to pass the step explicitly."
)
})
.0;
self.step_fixed_dt(n, dt_seconds)
}
}