Switch over to Tokio and drop web for now
This commit is contained in:
parent
b4b9dc1d55
commit
4bcf78e361
1089
Cargo.lock
generated
1089
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"]
|
|
38
src/main.rs
38
src/main.rs
@ -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();
|
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
src/state.rs
12
src/state.rs
@ -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>>;
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user