diff --git a/src/main.rs b/src/main.rs index 59c7b9b..bb6fc4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,41 +3,21 @@ #[macro_use] extern crate rocket; +mod simulation; + use std::fmt::Write as FmtWrite; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; -use legion::prelude::*; -use rand::prelude::*; use rocket::State; -#[derive(Clone, Debug, PartialEq)] -struct Name { - name: String, -} +use simulation::{Object, Simulation}; -#[derive(Clone, Copy, Debug, PartialEq)] -struct Position { - x: f64, - y: f64, -} - -#[derive(Clone, Copy, Debug, PartialEq)] -struct Velocity { - dx: f64, - dy: f64, -} - -struct ObjectOutput { - pub name: String, - pub x: f64, - pub y: f64, -} struct SimState { pub iteration: u64, - pub objects: Vec + pub objects: Vec } type WrappedState = Arc>; @@ -59,41 +39,15 @@ fn index(sim: State) -> String { fn simulation(s: WrappedState) { std::thread::spawn(move || { - let universe = Universe::new(); - let mut world = universe.create_world(); - let mut rng = thread_rng(); + let mut simulation = Simulation::new(); - world.insert( - (), - (0..999).map(|n| { - ( - Name { name: format!("Entity {}", n)}, - Position { x: 0.0, y: 0.0 }, - Velocity { - dx: rng.gen_range(0.0, 1.0), - dy: rng.gen_range(0.0, 1.0), - }, - ) - }), - ); - - - loop { - let update_query = <(Write, Read)>::query(); - for (mut pos, vel) in update_query.iter(&mut world) { - pos.x += vel.dx; - pos.y += vel.dy; + loop { + simulation.update(); + { + let mut state = s.lock().unwrap(); + (*state).iteration += 1; + (*state).objects = simulation.render(); } - - let mut state = s.lock().unwrap(); - (*state).iteration += 1; - let mut result: Vec = vec![]; - - for (name, pos) in <(Read, Read)>::query().iter(&mut world) { - result.push(ObjectOutput{ name: name.name.clone(), x: pos.x, y: pos.y }); - } - (*state).objects = result; - thread::sleep(Duration::from_secs(1)) } }); diff --git a/src/simulation.rs b/src/simulation.rs new file mode 100644 index 0000000..66cd014 --- /dev/null +++ b/src/simulation.rs @@ -0,0 +1,71 @@ +use legion::prelude::*; +use rand::prelude::*; + +#[derive(Clone, Debug, PartialEq)] +struct Name { + name: String, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct Position { + x: f64, + y: f64, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct Velocity { + dx: f64, + dy: f64, +} + +pub struct Simulation { + world: World +} + +pub struct Object { + pub name: String, + pub x: f64, + pub y: f64, +} + +impl Simulation { + pub fn new() -> Simulation { + let universe = Universe::new(); + let mut world = universe.create_world(); + let mut rng = thread_rng(); + + world.insert( + (), + (0..999).map(|n| { + ( + Name { name: format!("Entity {}", n)}, + Position { x: 0.0, y: 0.0 }, + Velocity { + dx: rng.gen_range(0.0, 1.0), + dy: rng.gen_range(0.0, 1.0), + }, + ) + }), + ); + + Simulation {world} + } + + pub fn update(&mut self) { + let update_query = <(Write, Read)>::query(); + for (mut pos, vel) in update_query.iter(&mut self.world) { + pos.x += vel.dx; + pos.y += vel.dy; + } + } + + pub fn render(&mut self) -> Vec { + let mut result: Vec = vec![]; + + for (name, pos) in <(Read, Read)>::query().iter(&mut self.world) { + result.push(Object{ name: name.name.clone(), x: pos.x, y: pos.y }); + } + + result + } +}