Made Simulation struct

This commit is contained in:
skyeshroom 2021-08-11 13:21:12 -07:00
parent cd327c6acc
commit 3f9f0ee2fa
5 changed files with 83 additions and 63 deletions

2
Cargo.lock generated
View File

@ -4,4 +4,4 @@ version = 3
[[package]] [[package]]
name = "hypoloop" name = "hypoloop"
version = "0.1.1" version = "0.1.2"

View File

@ -1,7 +1,7 @@
[package] [package]
name = "hypoloop" name = "hypoloop"
description = "A low-level control loop for real-time and baked simulations." description = "A low-level control loop for real-time and baked simulations."
version = "0.1.1" version = "0.1.2"
edition = "2018" edition = "2018"
license = "GPL-3.0" license = "GPL-3.0"
repository = "https://github.com/skyeterran/hypoloop" repository = "https://github.com/skyeterran/hypoloop"

View File

@ -6,4 +6,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
hypoloop = "0.1.1" hypoloop = {version = "0.1.1", path = "D:/Code/hypoloop"}

View File

@ -1,3 +1,9 @@
use hypoloop::Simulation;
fn main() { fn main() {
hypoloop::run_simulation(); // create sim
let mut sim = Simulation::new();
// run sim
sim.run();
} }

View File

@ -1,21 +1,33 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
// sim constants
// UPDATE_INTERVAL is the minimum delay (in milliseconds) between update ticks
// TIMESCALE is the rate of the simulation proportional to real-time
// if REALTIME is false, the simulation runs as fast as possible and doesn't run the display function
const UPDATE_INTERVAL: u32 = 40;
const TIMESCALE: f32 = 1.0;
const REALTIME: bool = true;
// debug constants // debug constants
const DEBUG_LOOP: bool = false; const DEBUG_LOOP: bool = false;
const DEBUG_TIME: bool = true; const DEBUG_TIME: bool = true;
pub fn run_simulation() { /// Contains all per-simulation logic and state
// allow the simulation to be stopped from within the loop (by setting simulate to false) // update_interval is the minimum delay (in milliseconds) between update ticks
let mut simulate: bool = true; // timescale is the rate of the simulation proportional to real-time
// if realtime is false, the simulation runs as fast as possible and doesn't run the display function
pub struct Simulation {
update_interval: u32,
timescale: f32,
realtime: bool,
simulate: bool
}
impl Simulation {
// Creates a new simulation with default values
pub fn new() -> Simulation {
Simulation {
update_interval: 40,
timescale: 1.0,
realtime: true,
simulate: true
}
}
/// Initializes and runs the simulation
pub fn run(&self) {
// start the clock to keep track of real time // start the clock to keep track of real time
let clock_start = Instant::now(); let clock_start = Instant::now();
@ -26,24 +38,24 @@ pub fn run_simulation() {
let mut irl_time = Duration::new(0, 0); let mut irl_time = Duration::new(0, 0);
let mut sim_time = Duration::new(0, 0); let mut sim_time = Duration::new(0, 0);
while simulate { while self.simulate {
// TODO - support frameskips // TODO - support frameskips
if !REALTIME || delta_time(last_tick) >= UPDATE_INTERVAL { if !self.realtime || delta_time(last_tick) >= self.update_interval {
// mutable delta time and timescale for flexibility // mutable delta time and timescale for flexibility
let mut current_timescale: f32; let mut current_timescale: f32;
let mut current_delta_time: u32; let mut current_delta_time: u32;
let elapsed_time = Instant::now().duration_since(last_tick); let elapsed_time = Instant::now().duration_since(last_tick);
// update clocks // update clocks
if REALTIME { if self.realtime {
current_timescale = TIMESCALE; current_timescale = self.timescale;
current_delta_time = delta_time(last_tick); current_delta_time = delta_time(last_tick);
sim_time += elapsed_time.mul_f32(TIMESCALE); sim_time += elapsed_time.mul_f32(self.timescale);
irl_time += elapsed_time; irl_time += elapsed_time;
} else { } else {
current_timescale = 1.0; current_timescale = 1.0;
current_delta_time = UPDATE_INTERVAL; current_delta_time = self.update_interval;
sim_time += Duration::from_millis(UPDATE_INTERVAL as u64); sim_time += Duration::from_millis(self.update_interval as u64);
irl_time = Instant::now().duration_since(clock_start); irl_time = Instant::now().duration_since(clock_start);
} }
@ -51,7 +63,7 @@ pub fn run_simulation() {
if DEBUG_TIME { if DEBUG_TIME {
let loop_delay_ms = elapsed_time.as_nanos() as f32 / 1_000_000.0; let loop_delay_ms = elapsed_time.as_nanos() as f32 / 1_000_000.0;
let loop_rate_hz = 1000.0 / loop_delay_ms; let loop_rate_hz = 1000.0 / loop_delay_ms;
println!("REALTIME: {} | IRL time: {}ms | Sim time: {}ms | Tick delay/rate: {}ms/{}hz", REALTIME, irl_time.as_millis(), sim_time.as_millis(), loop_delay_ms, loop_rate_hz); println!("Realtime: {} | IRL time: {}ms | Sim time: {}ms | Tick delay/rate: {}ms/{}hz", self.realtime, irl_time.as_millis(), sim_time.as_millis(), loop_delay_ms, loop_rate_hz);
} }
// update // update
@ -62,11 +74,13 @@ pub fn run_simulation() {
} }
// display // display
if REALTIME { if self.realtime {
display(delta_time(last_tick), TIMESCALE); display(delta_time(last_tick), self.timescale, self.update_interval);
} }
} }
} }
}
// update function // update function
// this is where all your per-tick logic should go // this is where all your per-tick logic should go
@ -82,14 +96,14 @@ fn update(delta_time: u32, timescale: f32) {
// display function // display function
// this is where you should call a render function // this is where you should call a render function
fn display(delta_time: u32, timescale: f32) { fn display(delta_time: u32, timescale: f32, update_interval: u32) {
// DEBUG // DEBUG
if DEBUG_LOOP { if DEBUG_LOOP {
println!("Displaying..."); println!("Displaying...");
} }
// use interpolation to smooth display values between ticks // use interpolation to smooth display values between ticks
let interpolation: f32 = delta_time as f32 / UPDATE_INTERVAL as f32 * timescale; let interpolation: f32 = delta_time as f32 / update_interval as f32 * timescale;
} }
// gets the time in milliseconds that's elapsed since the earlier Instant // gets the time in milliseconds that's elapsed since the earlier Instant