Made Simulation struct
This commit is contained in:
parent
cd327c6acc
commit
3f9f0ee2fa
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -4,4 +4,4 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hypoloop"
|
name = "hypoloop"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
|
@ -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"
|
||||||
|
@ -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"}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
132
src/lib.rs
132
src/lib.rs
@ -1,73 +1,87 @@
|
|||||||
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
|
||||||
// start the clock to keep track of real time
|
pub struct Simulation {
|
||||||
let clock_start = Instant::now();
|
update_interval: u32,
|
||||||
|
timescale: f32,
|
||||||
|
realtime: bool,
|
||||||
|
simulate: bool
|
||||||
|
}
|
||||||
|
|
||||||
// keep track of the last tick time
|
impl Simulation {
|
||||||
let mut last_tick = Instant::now();
|
// Creates a new simulation with default values
|
||||||
|
pub fn new() -> Simulation {
|
||||||
// real-time and sim-time clocks
|
Simulation {
|
||||||
let mut irl_time = Duration::new(0, 0);
|
update_interval: 40,
|
||||||
let mut sim_time = Duration::new(0, 0);
|
timescale: 1.0,
|
||||||
|
realtime: true,
|
||||||
while simulate {
|
simulate: true
|
||||||
// TODO - support frameskips
|
|
||||||
if !REALTIME || delta_time(last_tick) >= UPDATE_INTERVAL {
|
|
||||||
// mutable delta time and timescale for flexibility
|
|
||||||
let mut current_timescale: f32;
|
|
||||||
let mut current_delta_time: u32;
|
|
||||||
let elapsed_time = Instant::now().duration_since(last_tick);
|
|
||||||
|
|
||||||
// update clocks
|
|
||||||
if REALTIME {
|
|
||||||
current_timescale = TIMESCALE;
|
|
||||||
current_delta_time = delta_time(last_tick);
|
|
||||||
sim_time += elapsed_time.mul_f32(TIMESCALE);
|
|
||||||
irl_time += elapsed_time;
|
|
||||||
} else {
|
|
||||||
current_timescale = 1.0;
|
|
||||||
current_delta_time = UPDATE_INTERVAL;
|
|
||||||
sim_time += Duration::from_millis(UPDATE_INTERVAL as u64);
|
|
||||||
irl_time = Instant::now().duration_since(clock_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
if DEBUG_TIME {
|
|
||||||
let loop_delay_ms = elapsed_time.as_nanos() as f32 / 1_000_000.0;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update
|
|
||||||
update(current_delta_time, current_timescale);
|
|
||||||
|
|
||||||
// record last tick time
|
|
||||||
last_tick = Instant::now();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// display
|
/// Initializes and runs the simulation
|
||||||
if REALTIME {
|
pub fn run(&self) {
|
||||||
display(delta_time(last_tick), TIMESCALE);
|
// start the clock to keep track of real time
|
||||||
|
let clock_start = Instant::now();
|
||||||
|
|
||||||
|
// keep track of the last tick time
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
|
||||||
|
// real-time and sim-time clocks
|
||||||
|
let mut irl_time = Duration::new(0, 0);
|
||||||
|
let mut sim_time = Duration::new(0, 0);
|
||||||
|
|
||||||
|
while self.simulate {
|
||||||
|
// TODO - support frameskips
|
||||||
|
if !self.realtime || delta_time(last_tick) >= self.update_interval {
|
||||||
|
// mutable delta time and timescale for flexibility
|
||||||
|
let mut current_timescale: f32;
|
||||||
|
let mut current_delta_time: u32;
|
||||||
|
let elapsed_time = Instant::now().duration_since(last_tick);
|
||||||
|
|
||||||
|
// update clocks
|
||||||
|
if self.realtime {
|
||||||
|
current_timescale = self.timescale;
|
||||||
|
current_delta_time = delta_time(last_tick);
|
||||||
|
sim_time += elapsed_time.mul_f32(self.timescale);
|
||||||
|
irl_time += elapsed_time;
|
||||||
|
} else {
|
||||||
|
current_timescale = 1.0;
|
||||||
|
current_delta_time = self.update_interval;
|
||||||
|
sim_time += Duration::from_millis(self.update_interval as u64);
|
||||||
|
irl_time = Instant::now().duration_since(clock_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
if DEBUG_TIME {
|
||||||
|
let loop_delay_ms = elapsed_time.as_nanos() as f32 / 1_000_000.0;
|
||||||
|
let loop_rate_hz = 1000.0 / loop_delay_ms;
|
||||||
|
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(current_delta_time, current_timescale);
|
||||||
|
|
||||||
|
// record last tick time
|
||||||
|
last_tick = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
// display
|
||||||
|
if self.realtime {
|
||||||
|
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
|
||||||
fn update(delta_time: u32, timescale: f32) {
|
fn update(delta_time: u32, timescale: f32) {
|
||||||
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user