multiverse

This commit is contained in:
Skye Terran 2021-08-13 01:46:56 -07:00
parent f35758609d
commit f0dc45a294
4 changed files with 58 additions and 3 deletions

View File

@ -4,6 +4,7 @@
- Constant update rate - Constant update rate
- Variable display rate - Variable display rate
- Arbitrary simulation timescale - Arbitrary simulation timescale
- Support for multiple simultaneous simulations with shared data
- Compatible with other libraries' built-in event loops - Compatible with other libraries' built-in event loops
- Real-time can be disabled for high-speed simulations - Real-time can be disabled for high-speed simulations

View File

@ -9,7 +9,7 @@ fn main() {
let mut x: f32 = 0.0; let mut x: f32 = 0.0;
// create a closure containing your update logic // create a closure containing your update logic
let mut update_logic = move |state: &mut State| { let mut tick = move |state: &mut State| {
// access loop metadata via the State object // access loop metadata via the State object
x += state.get_timestep(); x += state.get_timestep();
print!("x: {} | ", x); print!("x: {} | ", x);
@ -19,7 +19,7 @@ fn main() {
}; };
// create a closure containing your display logic // create a closure containing your display logic
let mut display_logic = move |state: &mut State| { let mut display = move |state: &mut State| {
// //
}; };
@ -28,6 +28,6 @@ fn main() {
sim.init(); sim.init();
loop { loop {
// "step" the sim forward // "step" the sim forward
sim.step(&mut update_logic, &mut display_logic); sim.step(&mut tick, &mut display);
} }
} }

49
examples/multiverse.rs Normal file
View File

@ -0,0 +1,49 @@
use std::time::Duration;
use hypoloop::core::{State, Loop};
// this is a demonstration of running two different Loops simultaneously, both acting on the same data
fn main() {
// create a vector of sim loops
let mut multiverse: Vec<&mut Loop> = vec![];
// Sim A
let mut sim_a = Loop::new();
sim_a.set_update_interval(40);
sim_a.mut_state().set_timescale(1.0);
multiverse.push(&mut sim_a);
// Sim B
// twice the speed and twice the updates
let mut sim_b = Loop::new();
sim_b.set_update_interval(40);
sim_b.mut_state().set_timescale(2.0);
multiverse.push(&mut sim_b);
// shared variable
let mut x = Duration::new(0,0);
// tick behavior
// note how "state" switches between Sim A and B but x doesn't
// I'm purposefully NOT moving ownership of x into this closure so that I can access it later
let mut tick = |state: &mut State| {
// access loop metadata via the State object
x = (x + state.get_sim_time()) / 2;
print!("Average sim time: {} | ", x.as_millis());
// print information about the current tick's timings
state.debug_time();
};
// create a closure containing your display logic
let mut display = move |state: &mut State| {
//
};
// run both sims simultaneously
sim_a.init();
sim_b.init();
loop {
sim_a.step(&mut tick, &mut display);
sim_b.step(&mut tick, &mut display);
}
}

View File

@ -136,6 +136,11 @@ pub mod core {
self.state.sim_time = Duration::new(0,0); self.state.sim_time = Duration::new(0,0);
} }
/// Returns a mutable reference to the Loop's State object
pub fn mut_state(&mut self) -> &mut State {
&mut self.state
}
/// Executes the per-loop logic (can be triggered manually so that hypoloop can be tied into external event loops) /// Executes the per-loop logic (can be triggered manually so that hypoloop can be tied into external event loops)
pub fn step(&mut self, mut update_callback: impl FnMut(&mut State), mut display_callback: impl FnMut(&mut State)) { pub fn step(&mut self, mut update_callback: impl FnMut(&mut State), mut display_callback: impl FnMut(&mut State)) {
// don't run if the simulation is paused // don't run if the simulation is paused