Timing improvements
parent
be2cca79b0
commit
188dc9eb89
|
@ -714,6 +714,7 @@ dependencies = [
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"galactica-content",
|
"galactica-content",
|
||||||
"galactica-galaxy",
|
"galactica-galaxy",
|
||||||
|
"galactica-util",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
"rand",
|
"rand",
|
||||||
"rapier2d",
|
"rapier2d",
|
||||||
|
|
|
@ -121,11 +121,11 @@ impl Game {
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
|
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
|
||||||
|
|
||||||
self.timing.start();
|
self.timing.start_frame();
|
||||||
|
self.timing.start_galaxy();
|
||||||
self.galaxy.step(t);
|
self.galaxy.step(t);
|
||||||
self.timing.mark_galaxy();
|
self.timing.mark_galaxy();
|
||||||
|
|
||||||
self.timing.start();
|
|
||||||
self.systemsim.step(StepResources {
|
self.systemsim.step(StepResources {
|
||||||
player: self.player,
|
player: self.player,
|
||||||
player_controls: ShipControls {
|
player_controls: ShipControls {
|
||||||
|
@ -137,9 +137,9 @@ impl Game {
|
||||||
ct: &self.content,
|
ct: &self.content,
|
||||||
gx: &mut self.galaxy,
|
gx: &mut self.galaxy,
|
||||||
particles: &mut self.new_particles,
|
particles: &mut self.new_particles,
|
||||||
|
timing: &mut self.timing,
|
||||||
t,
|
t,
|
||||||
});
|
});
|
||||||
self.timing.mark_physics();
|
|
||||||
|
|
||||||
if self.input.v_scroll != 0.0 {
|
if self.input.v_scroll != 0.0 {
|
||||||
self.camera.zoom = (self.camera.zoom + self.input.v_scroll).clamp(ZOOM_MIN, ZOOM_MAX);
|
self.camera.zoom = (self.camera.zoom + self.input.v_scroll).clamp(ZOOM_MIN, ZOOM_MAX);
|
||||||
|
@ -153,6 +153,7 @@ impl Game {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.last_update = Instant::now();
|
self.last_update = Instant::now();
|
||||||
|
self.timing.mark_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_frame_state(&mut self) -> RenderInput {
|
pub fn get_frame_state(&mut self) -> RenderInput {
|
||||||
|
@ -166,7 +167,7 @@ impl Game {
|
||||||
player_data: self.player,
|
player_data: self.player,
|
||||||
data: &self.galaxy,
|
data: &self.galaxy,
|
||||||
current_system: SystemHandle { index: 0 },
|
current_system: SystemHandle { index: 0 },
|
||||||
timing: &self.timing,
|
timing: &mut self.timing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub struct RenderInput<'a> {
|
||||||
pub particles: &'a mut Vec<ParticleBuilder>,
|
pub particles: &'a mut Vec<ParticleBuilder>,
|
||||||
|
|
||||||
/// Time we spent in each part of the game loop
|
/// Time we spent in each part of the game loop
|
||||||
pub timing: &'a Timing,
|
pub timing: &'a mut Timing,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renderer state. A reference to this struct is often passed to helper functions.
|
/// Renderer state. A reference to this struct is often passed to helper functions.
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
impl super::GPUState {
|
impl super::GPUState {
|
||||||
/// Main render function. Draws sprites on a window.
|
/// Main render function. Draws sprites on a window.
|
||||||
pub fn render(&mut self, input: RenderInput) -> Result<(), wgpu::SurfaceError> {
|
pub fn render(&mut self, input: RenderInput) -> Result<(), wgpu::SurfaceError> {
|
||||||
// Set up text renderer
|
input.timing.start_render();
|
||||||
|
|
||||||
let output = self.surface.get_current_texture()?;
|
let output = self.surface.get_current_texture()?;
|
||||||
let view = output.texture.create_view(&Default::default());
|
let view = output.texture.create_view(&Default::default());
|
||||||
|
@ -214,6 +214,7 @@ impl super::GPUState {
|
||||||
self.state.queue.submit(iter::once(encoder.finish()));
|
self.state.queue.submit(iter::once(encoder.finish()));
|
||||||
output.present();
|
output.present();
|
||||||
|
|
||||||
|
input.timing.mark_render();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds};
|
use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds};
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use crate::{datastructs::RenderState, RenderInput};
|
use crate::{datastructs::RenderState, RenderInput};
|
||||||
|
|
||||||
pub(super) struct FpsIndicator {
|
pub(super) struct FpsIndicator {
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
last_update: Instant,
|
|
||||||
update_counter: u32,
|
update_counter: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +19,6 @@ impl FpsIndicator {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
buffer,
|
buffer,
|
||||||
last_update: Instant::now(),
|
|
||||||
update_counter: 0,
|
update_counter: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,15 +36,16 @@ impl FpsIndicator {
|
||||||
self.buffer.set_text(
|
self.buffer.set_text(
|
||||||
&mut state.text_font_system,
|
&mut state.text_font_system,
|
||||||
&format!(
|
&format!(
|
||||||
"Game: {:.02?}\nPhys: {:.02?}\nRender: {:.02?}",
|
"Frame: {:04.02?}%\nGame: {:04.02?}%\nShips: {:04.02?}%\nPhys: {:04.02?}%\nRender: {:.02?}",
|
||||||
1.0 / input.timing.galaxy,
|
100.0 * (input.timing.frame / input.timing.render),
|
||||||
1.0 / input.timing.physics,
|
100.0 * (input.timing.galaxy / input.timing.frame),
|
||||||
1.0 / (self.last_update.elapsed().as_secs_f32() / 100.0)
|
100.0 * (input.timing.physics_sim / input.timing.frame),
|
||||||
|
100.0 * (input.timing.physics_ship / input.timing.frame),
|
||||||
|
1.0 / input.timing.render
|
||||||
),
|
),
|
||||||
Attrs::new().family(Family::SansSerif),
|
Attrs::new().family(Family::Monospace),
|
||||||
Shaping::Basic,
|
Shaping::Basic,
|
||||||
);
|
);
|
||||||
self.last_update = Instant::now();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_textarea(&self) -> TextArea {
|
pub fn get_textarea(&self) -> TextArea {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use glyphon::TextArea;
|
use glyphon::TextArea;
|
||||||
|
|
||||||
use crate::{datastructs::RenderState, RenderInput};
|
|
||||||
|
|
||||||
use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status};
|
use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status};
|
||||||
|
use crate::{datastructs::RenderState, RenderInput};
|
||||||
|
|
||||||
pub struct UiManager {
|
pub struct UiManager {
|
||||||
radar: Radar,
|
radar: Radar,
|
||||||
|
@ -26,7 +25,7 @@ impl UiManager {
|
||||||
self.fps.update(input, state);
|
self.fps.update(input, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_textareas(&self) -> impl Iterator<Item = TextArea> {
|
pub fn get_textareas(&self) -> [TextArea; 1] {
|
||||||
(0..1).map(|_| self.fps.get_textarea())
|
[self.fps.get_textarea()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
galactica-content = { workspace = true }
|
galactica-content = { workspace = true }
|
||||||
galactica-galaxy = { workspace = true }
|
galactica-galaxy = { workspace = true }
|
||||||
|
galactica-util = { workspace = true }
|
||||||
|
|
||||||
rapier2d = { workspace = true }
|
rapier2d = { workspace = true }
|
||||||
nalgebra = { workspace = true }
|
nalgebra = { workspace = true }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{objects::ShipControls, ParticleBuilder};
|
use crate::{objects::ShipControls, ParticleBuilder};
|
||||||
use galactica_content::Content;
|
use galactica_content::Content;
|
||||||
use galactica_galaxy::{Galaxy, GxShipHandle};
|
use galactica_galaxy::{Galaxy, GxShipHandle};
|
||||||
|
use galactica_util::timing::Timing;
|
||||||
|
|
||||||
/// External resources we need to compute time steps
|
/// External resources we need to compute time steps
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -22,4 +23,7 @@ pub struct StepResources<'a> {
|
||||||
|
|
||||||
/// The ship that the player controls
|
/// The ship that the player controls
|
||||||
pub player: GxShipHandle,
|
pub player: GxShipHandle,
|
||||||
|
|
||||||
|
/// Record detailed frame timing breakdown
|
||||||
|
pub timing: &'a mut Timing,
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,11 @@ impl SystemSim {
|
||||||
|
|
||||||
/// Step this physics system by `t` seconds
|
/// Step this physics system by `t` seconds
|
||||||
pub fn step(&mut self, mut res: StepResources) {
|
pub fn step(&mut self, mut res: StepResources) {
|
||||||
|
res.timing.start_physics_ships();
|
||||||
self.step_ships(&mut res);
|
self.step_ships(&mut res);
|
||||||
|
res.timing.mark_physics_ships();
|
||||||
|
|
||||||
|
res.timing.start_physics_sim();
|
||||||
|
|
||||||
// Update physics
|
// Update physics
|
||||||
self.wrapper.step(res.t, &self.collision_handler);
|
self.wrapper.step(res.t, &self.collision_handler);
|
||||||
|
@ -457,6 +461,8 @@ impl SystemSim {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.timing.mark_physics_sim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,42 +3,96 @@ use std::time::Instant;
|
||||||
|
|
||||||
/// Utility struct.
|
/// Utility struct.
|
||||||
/// Keeps track of the time we spent in each part of the game loop.
|
/// Keeps track of the time we spent in each part of the game loop.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Timing {
|
pub struct Timing {
|
||||||
timer: Option<Instant>,
|
/// The time we spent processing the whole frame
|
||||||
|
pub frame: f32,
|
||||||
|
frame_timer: Instant,
|
||||||
|
|
||||||
/// The time we spent simulating game state
|
/// The time we spent simulating game state
|
||||||
pub galaxy: f32,
|
pub galaxy: f32,
|
||||||
|
galaxy_timer: Instant,
|
||||||
|
|
||||||
/// The time we spent simulating physics
|
/// The time we spent simulating physics
|
||||||
pub physics: f32,
|
pub physics_sim: f32,
|
||||||
|
physics_sim_timer: Instant,
|
||||||
|
|
||||||
|
/// The time we spent updating physics ships
|
||||||
|
pub physics_ship: f32,
|
||||||
|
physics_ship_timer: Instant,
|
||||||
|
|
||||||
|
/// The time we spent simulating physics
|
||||||
|
pub render: f32,
|
||||||
|
render_timer: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: macros
|
||||||
|
// TODO: document each duration
|
||||||
|
|
||||||
impl Timing {
|
impl Timing {
|
||||||
/// Create a new timing struct
|
/// Create a new timing struct
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
timer: None,
|
frame: f32::NAN,
|
||||||
galaxy: f32::NAN,
|
galaxy: f32::NAN,
|
||||||
physics: f32::NAN,
|
physics_sim: f32::NAN,
|
||||||
|
physics_ship: f32::NAN,
|
||||||
|
render: f32::NAN,
|
||||||
|
galaxy_timer: Instant::now(),
|
||||||
|
physics_sim_timer: Instant::now(),
|
||||||
|
physics_ship_timer: Instant::now(),
|
||||||
|
render_timer: Instant::now(),
|
||||||
|
frame_timer: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start the timer
|
/// Start frame timer
|
||||||
pub fn start(&mut self) {
|
pub fn start_frame(&mut self) {
|
||||||
self.timer = Some(Instant::now());
|
self.frame_timer = Instant::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear timer and record galaxy simulation time.
|
/// Start galaxy timer
|
||||||
/// Assumes timer has been started
|
pub fn start_galaxy(&mut self) {
|
||||||
|
self.galaxy_timer = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start physics sim timer
|
||||||
|
pub fn start_physics_sim(&mut self) {
|
||||||
|
self.physics_sim_timer = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start physics ship timer
|
||||||
|
pub fn start_physics_ships(&mut self) {
|
||||||
|
self.physics_ship_timer = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start render timer
|
||||||
|
pub fn start_render(&mut self) {
|
||||||
|
self.render_timer = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record galaxy simulation time.
|
||||||
|
pub fn mark_frame(&mut self) {
|
||||||
|
self.frame = self.frame_timer.elapsed().as_secs_f32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record galaxy simulation time.
|
||||||
pub fn mark_galaxy(&mut self) {
|
pub fn mark_galaxy(&mut self) {
|
||||||
self.galaxy = self.timer.unwrap().elapsed().as_secs_f32();
|
self.galaxy = self.galaxy_timer.elapsed().as_secs_f32();
|
||||||
self.timer = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear timer and record physics simulation time
|
/// Record physics simulation time
|
||||||
/// Asumes timer has been started
|
pub fn mark_physics_sim(&mut self) {
|
||||||
pub fn mark_physics(&mut self) {
|
self.physics_sim = self.physics_sim_timer.elapsed().as_secs_f32();
|
||||||
self.physics = self.timer.unwrap().elapsed().as_secs_f32();
|
}
|
||||||
self.timer = None;
|
|
||||||
|
/// Record physics ship update time
|
||||||
|
pub fn mark_physics_ships(&mut self) {
|
||||||
|
self.physics_ship = self.physics_ship_timer.elapsed().as_secs_f32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record physics simulation time
|
||||||
|
pub fn mark_render(&mut self) {
|
||||||
|
self.render = self.render_timer.elapsed().as_secs_f32();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue