// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub struct Counters {
mut enabled : Bool
step_time : Timer
custom : Timer
stages : StagesCounters
cd : CollisionDetectionCounters
solver : SolverCounters
ccd : CCDCounters
}
///|
pub fn Counters::Counters(enabled : Bool) -> Counters {
{
enabled,
step_time: Timer(),
custom: Timer(),
stages: StagesCounters(),
cd: CollisionDetectionCounters(),
solver: SolverCounters(),
ccd: CCDCounters(),
}
}
///|
pub fn Counters::default() -> Counters {
Counters(false)
}
///|
pub fn Counters::enable(self : Counters) -> Unit {
self.enabled = true
}
///|
pub fn Counters::disable(self : Counters) -> Unit {
self.enabled = false
}
///|
pub fn Counters::enabled(self : Counters) -> Bool {
self.enabled
}
///|
pub fn Counters::step_started(self : Counters) -> Unit {
if self.enabled {
self.step_time.start()
}
}
///|
pub fn Counters::step_completed(self : Counters) -> Unit {
if self.enabled {
self.step_time.pause()
}
}
///|
pub fn Counters::step_time_ms(self : Counters) -> Double {
if self.enabled {
self.step_time.time_ms()
} else {
0.0
}
}
///|
pub fn Counters::custom_started(self : Counters) -> Unit {
if self.enabled {
self.custom.start()
}
}
///|
pub fn Counters::custom_completed(self : Counters) -> Unit {
if self.enabled {
self.custom.pause()
}
}
///|
pub fn Counters::custom_time_ms(self : Counters) -> Double {
if self.enabled {
self.custom.time_ms()
} else {
0.0
}
}
///|
pub fn Counters::custom_time(self : Counters) -> Double {
self.custom_time_ms()
}
///|
pub fn Counters::set_nconstraints(self : Counters, n : Int) -> Unit {
if self.enabled {
self.solver.set_nconstraints(n)
}
}
///|
pub fn Counters::set_ncontacts(self : Counters, n : Int) -> Unit {
if self.enabled {
self.solver.set_ncontacts(n)
}
}
///|
pub fn Counters::set_ncontact_pairs(self : Counters, n : Int) -> Unit {
if self.enabled {
self.cd.set_ncontact_pairs(n)
}
}
///|
pub fn Counters::reset(self : Counters) -> Unit {
if self.enabled {
self.step_time.reset()
self.custom.reset()
self.stages.reset()
self.cd.reset()
self.solver.reset()
self.ccd.reset()
}
}
///|
fn measure_started(enabled : Bool, timer : Timer) -> Unit {
if enabled {
timer.start()
}
}
///|
fn measure_completed(enabled : Bool, timer : Timer) -> Unit {
if enabled {
timer.pause()
}
}
///|
fn measure_time_ms(enabled : Bool, timer : Timer) -> Double {
if enabled {
timer.time_ms()
} else {
0.0
}
}
///|
pub fn Counters::update_started(self : Counters) -> Unit {
measure_started(self.enabled, self.stages.update_time)
}
///|
pub fn Counters::update_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.stages.update_time)
}
///|
pub fn Counters::update_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.stages.update_time)
}
///|
pub fn Counters::collision_detection_started(self : Counters) -> Unit {
measure_started(self.enabled, self.stages.collision_detection_time)
}
///|
pub fn Counters::collision_detection_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.stages.collision_detection_time)
}
///|
pub fn Counters::collision_detection_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.stages.collision_detection_time)
}
///|
pub fn Counters::island_construction_started(self : Counters) -> Unit {
measure_started(self.enabled, self.stages.island_construction_time)
}
///|
pub fn Counters::island_construction_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.stages.island_construction_time)
}
///|
pub fn Counters::island_construction_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.stages.island_construction_time)
}
///|
pub fn Counters::solver_started(self : Counters) -> Unit {
measure_started(self.enabled, self.stages.solver_time)
}
///|
pub fn Counters::solver_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.stages.solver_time)
}
///|
pub fn Counters::solver_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.stages.solver_time)
}
///|
pub fn Counters::ccd_started(self : Counters) -> Unit {
measure_started(self.enabled, self.stages.ccd_time)
}
///|
pub fn Counters::ccd_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.stages.ccd_time)
}
///|
pub fn Counters::ccd_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.stages.ccd_time)
}
///|
pub fn Counters::assembly_started(self : Counters) -> Unit {
measure_started(self.enabled, self.solver.velocity_assembly_time)
}
///|
pub fn Counters::assembly_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.solver.velocity_assembly_time)
}
///|
pub fn Counters::assembly_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.solver.velocity_assembly_time)
}
///|
pub fn Counters::velocity_resolution_started(self : Counters) -> Unit {
measure_started(self.enabled, self.solver.velocity_resolution_time)
}
///|
pub fn Counters::velocity_resolution_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.solver.velocity_resolution_time)
}
///|
pub fn Counters::velocity_resolution_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.solver.velocity_resolution_time)
}
///|
pub fn Counters::velocity_update_started(self : Counters) -> Unit {
measure_started(self.enabled, self.solver.velocity_update_time)
}
///|
pub fn Counters::velocity_update_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.solver.velocity_update_time)
}
///|
pub fn Counters::velocity_update_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.solver.velocity_update_time)
}
///|
pub fn Counters::broad_phase_started(self : Counters) -> Unit {
measure_started(self.enabled, self.cd.broad_phase_time)
}
///|
pub fn Counters::broad_phase_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.cd.broad_phase_time)
}
///|
pub fn Counters::broad_phase_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.cd.broad_phase_time)
}
///|
pub fn Counters::narrow_phase_started(self : Counters) -> Unit {
measure_started(self.enabled, self.cd.narrow_phase_time)
}
///|
pub fn Counters::narrow_phase_completed(self : Counters) -> Unit {
measure_completed(self.enabled, self.cd.narrow_phase_time)
}
///|
pub fn Counters::narrow_phase_time_ms(self : Counters) -> Double {
measure_time_ms(self.enabled, self.cd.narrow_phase_time)
}
///|
pub fn Counters::to_string(self : Counters) -> String {
let s = "Total timestep time: " +
self.step_time.to_string() +
"\n" +
self.stages.to_string() +
"\n" +
self.cd.to_string() +
"\n" +
self.solver.to_string() +
"\n" +
"Custom timer: " +
self.custom.to_string()
s
}