Switch over to Tokio and drop web for now

This commit is contained in:
Gender Shrapnel 2020-06-01 02:35:10 +02:00
parent b4b9dc1d55
commit 4bcf78e361
5 changed files with 154 additions and 1075 deletions

1089
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,5 @@ license = "AGPL-3.0-or-later"
[dependencies] [dependencies]
legion = "0.2.1" legion = "0.2.1"
rand = "0.7.3" rand = "0.7.3"
rocket = "0.4.4" tokio = { version = "0.2", features = ["full"] }
serde = { version = "1.0.111", features = ["derive"] }
[dependencies.rocket_contrib]
version = "0.4.5"
default-features = false
features = ["tera_templates"]

View File

@ -1,39 +1,19 @@
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
extern crate serde;
use std::sync::Arc;
use rocket::State as RocketState;
use rocket_contrib::templates::Template;
mod simulation; mod simulation;
mod state; mod state;
use simulation::Simulation; use simulation::Simulation;
use state::WrappedState;
#[get("/")] #[tokio::main]
fn index(sim: RocketState<WrappedState>) -> Template { async fn main() {
let state = sim.lock().unwrap();
Template::render("stuff", state.clone())
}
fn main() {
let mut simulation = Simulation::new(); let mut simulation = Simulation::new();
let state = Arc::clone(&simulation.state); let mut state_channel = simulation.state();
std::thread::spawn(move || { tokio::spawn(async move {
simulation.run(); simulation.run().await;
}); });
rocket::ignite() loop {
.attach(Template::fairing()) let state = state_channel.recv().await.unwrap();
.manage(state) println!("Iteration {}", state.iteration)
.mount("/", routes![index]) }
.launch();
} }

View File

@ -1,12 +1,10 @@
use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant};
use std::thread;
use std::time::Duration;
use legion::prelude::*; use legion::prelude::*;
use rand::prelude::*; use rand::prelude::*;
use tokio::{sync::watch, time};
use crate::state::{State, WrappedState, Object}; use crate::state::{Object, State};
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
struct Name { struct Name {
@ -27,7 +25,24 @@ struct Velocity {
pub struct Simulation { pub struct Simulation {
world: World, world: World,
pub state: WrappedState, iteration: u64,
last: Instant,
tx: watch::Sender<State>,
rx: watch::Receiver<State>,
}
fn render(world: &mut World) -> Vec<Object> {
let mut result = vec![];
for (name, pos) in <(Read<Name>, Read<Position>)>::query().iter(world) {
result.push(Object {
name: name.name.clone(),
x: pos.x,
y: pos.y,
});
}
result
} }
impl Simulation { impl Simulation {
@ -40,7 +55,9 @@ impl Simulation {
(), (),
(0..999).map(|n| { (0..999).map(|n| {
( (
Name { name: format!("Entity {}", n)}, Name {
name: format!("Entity {}", n),
},
Position { x: 0.0, y: 0.0 }, Position { x: 0.0, y: 0.0 },
Velocity { Velocity {
dx: rng.gen_range(0.0, 1.0), dx: rng.gen_range(0.0, 1.0),
@ -50,40 +67,46 @@ impl Simulation {
}), }),
); );
let mut result = Self {world, state: Arc::new(Mutex::new(State { let (tx, rx) = watch::channel(State {
iteration: 0, objects: vec![] iteration: 0,
}))}; objects: render(&mut world),
});
result.render(); Self { world, last: Instant::now(), iteration: 0, tx, rx }
result
} }
pub fn update(&mut self) { fn update(&mut self) {
let update_query = <(Write<Position>, Read<Velocity>)>::query(); let update_query = <(Write<Position>, Read<Velocity>)>::query();
let now = Instant::now();
let dt = now.duration_since(self.last);
for (mut pos, vel) in update_query.iter(&mut self.world) { for (mut pos, vel) in update_query.iter(&mut self.world) {
pos.x += vel.dx; pos.x += vel.dx * dt.as_secs_f64();
pos.y += vel.dy; pos.y += vel.dy * dt.as_secs_f64();
} }
self.state.lock().unwrap().iteration += 1; self.last = now;
self.iteration += 1;
} }
fn render(&mut self) { fn render(&mut self) -> State {
let mut state = self.state.lock().unwrap(); State {
iteration: self.iteration,
state.objects = vec![]; objects: render(&mut self.world),
for (name, pos) in <(Read<Name>, Read<Position>)>::query().iter(&mut self.world) {
state.objects.push(Object{ name: name.name.clone(), x: pos.x, y: pos.y });
} }
} }
pub fn run(&mut self) { pub async fn run(&mut self) {
let mut interval = time::interval(Duration::from_millis(1000 / 60));
loop { loop {
self.update(); self.update();
self.render(); let state = self.render();
self.tx.broadcast(state).unwrap();
thread::sleep(Duration::from_secs(1)) interval.tick().await;
} }
} }
pub fn state(&mut self) -> watch::Receiver<State> {
self.rx.clone()
}
} }

View File

@ -1,18 +1,12 @@
use std::sync::{Arc, Mutex}; #[derive(Clone, Debug)]
use serde::Serialize;
#[derive(Clone, Serialize)]
pub struct Object { pub struct Object {
pub name: String, pub name: String,
pub x: f64, pub x: f64,
pub y: f64, pub y: f64,
} }
#[derive(Clone, Serialize)] #[derive(Clone, Debug)]
pub struct State { pub struct State {
pub iteration: u64, pub iteration: u64,
pub objects: Vec<Object> pub objects: Vec<Object>,
} }
pub type WrappedState = Arc<Mutex<State>>;