mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-06 21:15:48 -06:00
fix: avoid padding jitter with constant name padding, minor timing calculation fixes
This commit is contained in:
@@ -89,7 +89,7 @@ impl App {
|
|||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let dt = self.last_tick.elapsed().as_secs_f32();
|
let dt = self.last_tick.elapsed().as_secs_f32();
|
||||||
self.last_tick = Instant::now();
|
self.last_tick = start;
|
||||||
|
|
||||||
let exit = self.game.tick(dt);
|
let exit = self.game.tick(dt);
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use glam::UVec2;
|
|||||||
///
|
///
|
||||||
/// Calculated as 1/60th of a second (≈16.67ms).
|
/// Calculated as 1/60th of a second (≈16.67ms).
|
||||||
///
|
///
|
||||||
/// Written out explicitly to satisfy const-eval constraints.
|
/// Uses integer arithmetic to avoid floating-point precision loss.
|
||||||
pub const LOOP_TIME: Duration = Duration::from_nanos((1_000_000_000.0 / 60.0) as u64);
|
pub const LOOP_TIME: Duration = Duration::from_nanos(1_000_000_000 / 60);
|
||||||
|
|
||||||
/// The size of each cell, in pixels.
|
/// The size of each cell, in pixels.
|
||||||
pub const CELL_SIZE: u32 = 8;
|
pub const CELL_SIZE: u32 = 8;
|
||||||
|
|||||||
@@ -138,14 +138,12 @@ pub fn input_system(
|
|||||||
|
|
||||||
// Warn if the smallvec was heap allocated due to exceeding stack capacity
|
// Warn if the smallvec was heap allocated due to exceeding stack capacity
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
if frame_events.len() > frame_events.capacity() {
|
||||||
if frame_events.len() > frame_events.capacity() {
|
tracing::warn!(
|
||||||
tracing::warn!(
|
"More than {} events in a frame, consider adjusting stack capacity: {:?}",
|
||||||
"More than {} events in a frame, consider adjusting stack capacity: {:?}",
|
frame_events.capacity(),
|
||||||
frame_events.capacity(),
|
frame_events
|
||||||
frame_events
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle non-keyboard events inline and build a simplified keyboard event stream.
|
// Handle non-keyboard events inline and build a simplified keyboard event stream.
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use parking_lot::{Mutex, RwLock};
|
|||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use strum::EnumCount;
|
use strum::{EnumCount, IntoEnumIterator};
|
||||||
use strum_macros::{EnumCount, IntoStaticStr};
|
use strum_macros::{EnumCount, EnumIter, IntoStaticStr};
|
||||||
use thousands::Separable;
|
use thousands::Separable;
|
||||||
|
|
||||||
/// The maximum number of systems that can be profiled. Must not be exceeded, or it will panic.
|
/// The maximum number of systems that can be profiled. Must not be exceeded, or it will panic.
|
||||||
@@ -16,7 +16,7 @@ const MAX_SYSTEMS: usize = SystemId::COUNT;
|
|||||||
/// The number of durations to keep in the circular buffer.
|
/// The number of durations to keep in the circular buffer.
|
||||||
const TIMING_WINDOW_SIZE: usize = 30;
|
const TIMING_WINDOW_SIZE: usize = 30;
|
||||||
|
|
||||||
#[derive(EnumCount, IntoStaticStr, Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(EnumCount, EnumIter, IntoStaticStr, Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
pub enum SystemId {
|
pub enum SystemId {
|
||||||
Input,
|
Input,
|
||||||
PlayerControls,
|
PlayerControls,
|
||||||
@@ -96,7 +96,7 @@ impl SystemTimings {
|
|||||||
let sum: f64 = durations.iter().sum();
|
let sum: f64 = durations.iter().sum();
|
||||||
let mean = sum / count;
|
let mean = sum / count;
|
||||||
|
|
||||||
let variance = durations.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / count;
|
let variance = durations.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (count - 1.0).max(1.0);
|
||||||
let std_dev = variance.sqrt();
|
let std_dev = variance.sqrt();
|
||||||
|
|
||||||
stats.insert(
|
stats.insert(
|
||||||
@@ -128,7 +128,7 @@ impl SystemTimings {
|
|||||||
diff_secs * diff_secs
|
diff_secs * diff_secs
|
||||||
})
|
})
|
||||||
.sum::<f64>()
|
.sum::<f64>()
|
||||||
/ duration_sums.len() as f64;
|
/ (duration_sums.len() - 1).max(1) as f64;
|
||||||
let std_dev_secs = variance.sqrt();
|
let std_dev_secs = variance.sqrt();
|
||||||
|
|
||||||
(mean, Duration::from_secs_f64(std_dev_secs))
|
(mean, Duration::from_secs_f64(std_dev_secs))
|
||||||
@@ -250,17 +250,22 @@ pub fn format_timing_display(
|
|||||||
})
|
})
|
||||||
.collect::<SmallVec<[Entry; 12]>>();
|
.collect::<SmallVec<[Entry; 12]>>();
|
||||||
|
|
||||||
let (max_name_width, max_avg_int_width, max_avg_decimal_width, max_std_int_width, max_std_decimal_width) = entries
|
let (max_avg_int_width, max_avg_decimal_width, max_std_int_width, max_std_decimal_width) =
|
||||||
.iter()
|
entries
|
||||||
.fold((0, 0, 3, 0, 3), |(name_w, avg_int_w, avg_dec_w, std_int_w, std_dec_w), e| {
|
.iter()
|
||||||
(
|
.fold((0, 3, 0, 3), |(avg_int_w, avg_dec_w, std_int_w, std_dec_w), e| {
|
||||||
name_w.max(e.name.len()),
|
(
|
||||||
avg_int_w.max(e.avg_int.width() as usize),
|
avg_int_w.max(e.avg_int.width() as usize),
|
||||||
avg_dec_w.max(e.avg_decimal.width() as usize),
|
avg_dec_w.max(e.avg_decimal.width() as usize),
|
||||||
std_int_w.max(e.std_int.width() as usize),
|
std_int_w.max(e.std_int.width() as usize),
|
||||||
std_dec_w.max(e.std_decimal.width() as usize),
|
std_dec_w.max(e.std_decimal.width() as usize),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let max_name_width = SystemId::iter()
|
||||||
|
.map(|id| id.to_string().len())
|
||||||
|
.max()
|
||||||
|
.expect("SystemId::iter() returned an empty iterator");
|
||||||
|
|
||||||
entries.iter().map(|e| {
|
entries.iter().map(|e| {
|
||||||
format!(
|
format!(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ fn test_timing_statistics() {
|
|||||||
timings.add_timing(SystemId::Blinking, Duration::from_millis(3));
|
timings.add_timing(SystemId::Blinking, Duration::from_millis(3));
|
||||||
timings.add_timing(SystemId::Blinking, Duration::from_millis(2));
|
timings.add_timing(SystemId::Blinking, Duration::from_millis(2));
|
||||||
timings.add_timing(SystemId::Blinking, Duration::from_millis(1));
|
timings.add_timing(SystemId::Blinking, Duration::from_millis(1));
|
||||||
|
|
||||||
fn close_enough(a: Duration, b: Duration) -> bool {
|
fn close_enough(a: Duration, b: Duration) -> bool {
|
||||||
if a > b {
|
if a > b {
|
||||||
a - b < Duration::from_micros(500) // 0.1ms
|
a - b < Duration::from_micros(500) // 0.1ms
|
||||||
@@ -36,25 +37,8 @@ fn test_timing_statistics() {
|
|||||||
total_avg
|
total_avg
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
close_enough(total_std, Duration::from_millis(12)),
|
close_enough(total_std, Duration::from_millis(17)),
|
||||||
"total_std: {:?}",
|
"total_std: {:?}",
|
||||||
total_std
|
total_std
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_window_size_limit() {
|
|
||||||
// let timings = SystemTimings::default();
|
|
||||||
|
|
||||||
// // Add more than 90 timings to test window size limit
|
|
||||||
// for i in 0..100 {
|
|
||||||
// timings.add_timing("test_system", Duration::from_millis(i));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let stats = timings.get_stats();
|
|
||||||
// let (avg, _) = stats.get("test_system").unwrap();
|
|
||||||
|
|
||||||
// // Should only keep the last 90 values, so average should be around 55ms
|
|
||||||
// // (average of 10-99)
|
|
||||||
// assert!((avg.as_millis() as f64 - 55.0).abs() < 5.0);
|
|
||||||
// }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user