1use core::time::Duration;
4use std::fmt::{Display, Formatter, Result};
5
6pub use self::ccd_counters::CCDCounters;
7pub use self::collision_detection_counters::CollisionDetectionCounters;
8pub use self::solver_counters::SolverCounters;
9pub use self::stages_counters::StagesCounters;
10pub use self::timer::Timer;
11
12mod ccd_counters;
13mod collision_detection_counters;
14mod solver_counters;
15mod stages_counters;
16mod timer;
17
18#[derive(Clone, Copy)]
20pub struct Counters {
21 pub enabled: bool,
23 pub step_time: Timer,
25 pub custom: Timer,
27 pub stages: StagesCounters,
29 pub cd: CollisionDetectionCounters,
31 pub solver: SolverCounters,
33 pub ccd: CCDCounters,
35}
36
37impl Counters {
38 pub fn new(enabled: bool) -> Self {
40 Counters {
41 enabled,
42 step_time: Timer::new(),
43 custom: Timer::new(),
44 stages: StagesCounters::new(),
45 cd: CollisionDetectionCounters::new(),
46 solver: SolverCounters::new(),
47 ccd: CCDCounters::new(),
48 }
49 }
50
51 pub fn enable(&mut self) {
53 self.enabled = true;
54 }
55
56 pub fn enabled(&self) -> bool {
58 self.enabled
59 }
60
61 pub fn disable(&mut self) {
63 self.enabled = false;
64 }
65
66 pub fn step_started(&mut self) {
68 if self.enabled {
69 self.step_time.start();
70 }
71 }
72
73 pub fn step_completed(&mut self) {
75 if self.enabled {
76 self.step_time.pause();
77 }
78 }
79
80 pub fn step_time(&self) -> Duration {
82 self.step_time.time()
83 }
84
85 pub fn step_time_ms(&self) -> f64 {
87 self.step_time.time_ms()
88 }
89
90 pub fn custom_started(&mut self) {
92 if self.enabled {
93 self.custom.start();
94 }
95 }
96
97 pub fn custom_completed(&mut self) {
99 if self.enabled {
100 self.custom.pause();
101 }
102 }
103
104 pub fn custom_time(&self) -> Duration {
106 self.custom.time()
107 }
108
109 pub fn custom_time_ms(&self) -> f64 {
111 self.custom.time_ms()
112 }
113
114 pub fn set_nconstraints(&mut self, n: usize) {
116 self.solver.nconstraints = n;
117 }
118
119 pub fn set_ncontacts(&mut self, n: usize) {
121 self.solver.ncontacts = n;
122 }
123
124 pub fn set_ncontact_pairs(&mut self, n: usize) {
126 self.cd.ncontact_pairs = n;
127 }
128
129 pub fn reset(&mut self) {
131 if self.enabled {
132 self.step_time.reset();
133 self.custom.reset();
134 self.stages.reset();
135 self.cd.reset();
136 self.solver.reset();
137 self.ccd.reset();
138 }
139 }
140}
141
142macro_rules! measure_method {
143 ($started:ident, $stopped:ident, $time_ms:ident, $info:ident. $timer:ident) => {
144 impl Counters {
145 pub fn $started(&mut self) {
147 if self.enabled {
148 self.$info.$timer.start()
149 }
150 }
151
152 pub fn $stopped(&mut self) {
154 if self.enabled {
155 self.$info.$timer.pause()
156 }
157 }
158
159 pub fn $time_ms(&self) -> f64 {
161 if self.enabled {
162 self.$info.$timer.time_ms()
163 } else {
164 0.0
165 }
166 }
167 }
168 };
169}
170
171measure_method!(
172 update_started,
173 update_completed,
174 update_time_ms,
175 stages.update_time
176);
177measure_method!(
178 collision_detection_started,
179 collision_detection_completed,
180 collision_detection_time_ms,
181 stages.collision_detection_time
182);
183measure_method!(
184 island_construction_started,
185 island_construction_completed,
186 island_construction_time_ms,
187 stages.island_construction_time
188);
189measure_method!(
190 solver_started,
191 solver_completed,
192 solver_time_ms,
193 stages.solver_time
194);
195measure_method!(ccd_started, ccd_completed, ccd_time_ms, stages.ccd_time);
196
197measure_method!(
198 assembly_started,
199 assembly_completed,
200 assembly_time_ms,
201 solver.velocity_assembly_time
202);
203measure_method!(
204 velocity_resolution_started,
205 velocity_resolution_completed,
206 velocity_resolution_time_ms,
207 solver.velocity_resolution_time
208);
209measure_method!(
210 velocity_update_started,
211 velocity_update_completed,
212 velocity_update_time_ms,
213 solver.velocity_update_time
214);
215measure_method!(
216 broad_phase_started,
217 broad_phase_completed,
218 broad_phase_time_ms,
219 cd.broad_phase_time
220);
221measure_method!(
222 narrow_phase_started,
223 narrow_phase_completed,
224 narrow_phase_time_ms,
225 cd.narrow_phase_time
226);
227
228impl Display for Counters {
229 fn fmt(&self, f: &mut Formatter) -> Result {
230 writeln!(f, "Total timestep time: {}", self.step_time)?;
231 self.stages.fmt(f)?;
232 self.cd.fmt(f)?;
233 self.solver.fmt(f)?;
234 writeln!(f, "Custom timer: {}", self.custom)
235 }
236}
237
238impl Default for Counters {
239 fn default() -> Self {
240 Self::new(false)
241 }
242}