From f0dc45a29496a948e59290c8c7fbb3a651d4272c Mon Sep 17 00:00:00 2001 From: Skye Terran Date: Fri, 13 Aug 2021 01:46:56 -0700 Subject: [PATCH] multiverse --- README.md | 1 + examples/basics.rs | 6 +++--- examples/multiverse.rs | 49 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 examples/multiverse.rs diff --git a/README.md b/README.md index 985d441..af74a89 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ - Constant update rate - Variable display rate - Arbitrary simulation timescale +- Support for multiple simultaneous simulations with shared data - Compatible with other libraries' built-in event loops - Real-time can be disabled for high-speed simulations diff --git a/examples/basics.rs b/examples/basics.rs index b03a7ed..1bc2510 100644 --- a/examples/basics.rs +++ b/examples/basics.rs @@ -9,7 +9,7 @@ fn main() { let mut x: f32 = 0.0; // 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 x += state.get_timestep(); print!("x: {} | ", x); @@ -19,7 +19,7 @@ fn main() { }; // 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(); loop { // "step" the sim forward - sim.step(&mut update_logic, &mut display_logic); + sim.step(&mut tick, &mut display); } } \ No newline at end of file diff --git a/examples/multiverse.rs b/examples/multiverse.rs new file mode 100644 index 0000000..f0982df --- /dev/null +++ b/examples/multiverse.rs @@ -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); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fefb179..bd8cd93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,6 +136,11 @@ pub mod core { 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) 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