use core::time::Duration;
use std::fmt::{Display, Formatter, Result};
pub use self::ccd_counters::CCDCounters;
pub use self::collision_detection_counters::CollisionDetectionCounters;
pub use self::solver_counters::SolverCounters;
pub use self::stages_counters::StagesCounters;
pub use self::timer::Timer;
mod ccd_counters;
mod collision_detection_counters;
mod solver_counters;
mod stages_counters;
mod timer;
#[derive(Clone, Copy)]
pub struct Counters {
pub enabled: bool,
pub step_time: Timer,
pub custom: Timer,
pub stages: StagesCounters,
pub cd: CollisionDetectionCounters,
pub solver: SolverCounters,
pub ccd: CCDCounters,
}
impl Counters {
pub fn new(enabled: bool) -> Self {
Counters {
enabled,
step_time: Timer::new(),
custom: Timer::new(),
stages: StagesCounters::new(),
cd: CollisionDetectionCounters::new(),
solver: SolverCounters::new(),
ccd: CCDCounters::new(),
}
}
pub fn enable(&mut self) {
self.enabled = true;
}
pub fn enabled(&self) -> bool {
self.enabled
}
pub fn disable(&mut self) {
self.enabled = false;
}
pub fn step_started(&mut self) {
if self.enabled {
self.step_time.start();
}
}
pub fn step_completed(&mut self) {
if self.enabled {
self.step_time.pause();
}
}
pub fn step_time(&self) -> Duration {
self.step_time.time()
}
pub fn step_time_ms(&self) -> f64 {
self.step_time.time_ms()
}
pub fn custom_started(&mut self) {
if self.enabled {
self.custom.start();
}
}
pub fn custom_completed(&mut self) {
if self.enabled {
self.custom.pause();
}
}
pub fn custom_time(&self) -> Duration {
self.custom.time()
}
pub fn custom_time_ms(&self) -> f64 {
self.custom.time_ms()
}
pub fn set_nconstraints(&mut self, n: usize) {
self.solver.nconstraints = n;
}
pub fn set_ncontacts(&mut self, n: usize) {
self.solver.ncontacts = n;
}
pub fn set_ncontact_pairs(&mut self, n: usize) {
self.cd.ncontact_pairs = n;
}
pub fn reset(&mut self) {
if self.enabled {
self.step_time.reset();
self.custom.reset();
self.stages.reset();
self.cd.reset();
self.solver.reset();
self.ccd.reset();
}
}
}
macro_rules! measure_method {
($started:ident, $stopped:ident, $time_ms:ident, $info:ident. $timer:ident) => {
impl Counters {
pub fn $started(&mut self) {
if self.enabled {
self.$info.$timer.start()
}
}
pub fn $stopped(&mut self) {
if self.enabled {
self.$info.$timer.pause()
}
}
pub fn $time_ms(&self) -> f64 {
if self.enabled {
self.$info.$timer.time_ms()
} else {
0.0
}
}
}
};
}
measure_method!(
update_started,
update_completed,
update_time_ms,
stages.update_time
);
measure_method!(
collision_detection_started,
collision_detection_completed,
collision_detection_time_ms,
stages.collision_detection_time
);
measure_method!(
island_construction_started,
island_construction_completed,
island_construction_time_ms,
stages.island_construction_time
);
measure_method!(
solver_started,
solver_completed,
solver_time_ms,
stages.solver_time
);
measure_method!(ccd_started, ccd_completed, ccd_time_ms, stages.ccd_time);
measure_method!(
query_pipeline_update_started,
query_pipeline_update_completed,
query_pipeline_update_time_ms,
stages.query_pipeline_time
);
measure_method!(
assembly_started,
assembly_completed,
assembly_time_ms,
solver.velocity_assembly_time
);
measure_method!(
velocity_resolution_started,
velocity_resolution_completed,
velocity_resolution_time_ms,
solver.velocity_resolution_time
);
measure_method!(
velocity_update_started,
velocity_update_completed,
velocity_update_time_ms,
solver.velocity_update_time
);
measure_method!(
broad_phase_started,
broad_phase_completed,
broad_phase_time_ms,
cd.broad_phase_time
);
measure_method!(
narrow_phase_started,
narrow_phase_completed,
narrow_phase_time_ms,
cd.narrow_phase_time
);
impl Display for Counters {
fn fmt(&self, f: &mut Formatter) -> Result {
writeln!(f, "Total timestep time: {}", self.step_time)?;
self.stages.fmt(f)?;
self.cd.fmt(f)?;
self.solver.fmt(f)?;
writeln!(f, "Custom timer: {}", self.custom)
}
}
impl Default for Counters {
fn default() -> Self {
Self::new(false)
}
}