48 lines
1.6 KiB
Rust
48 lines
1.6 KiB
Rust
|
|
mod world;
|
||
|
|
|
||
|
|
use std::sync::{Arc, Mutex};
|
||
|
|
use std::thread;
|
||
|
|
use std::time::Duration;
|
||
|
|
use tiny_http::{Header, Response, Server};
|
||
|
|
use world::World;
|
||
|
|
|
||
|
|
const INDEX: &str = include_str!("index.html");
|
||
|
|
|
||
|
|
fn main() {
|
||
|
|
let seed = std::env::args()
|
||
|
|
.nth(1)
|
||
|
|
.and_then(|s| s.parse().ok())
|
||
|
|
.unwrap_or(42u64);
|
||
|
|
let addr = std::env::var("SIM_ADDR").unwrap_or_else(|_| "127.0.0.1:7878".into());
|
||
|
|
let world = Arc::new(Mutex::new(World::new(seed)));
|
||
|
|
|
||
|
|
{
|
||
|
|
let world = Arc::clone(&world);
|
||
|
|
thread::spawn(move || {
|
||
|
|
loop {
|
||
|
|
world.lock().unwrap().step();
|
||
|
|
thread::sleep(Duration::from_millis(100));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
let server = Server::http(&addr).expect("failed to bind");
|
||
|
|
println!("Simulation running at http://{addr}");
|
||
|
|
for req in server.incoming_requests() {
|
||
|
|
let world = Arc::clone(&world);
|
||
|
|
thread::spawn(move || {
|
||
|
|
let (body, ctype) = match req.url() {
|
||
|
|
"/" => (INDEX.to_string(), "text/html; charset=utf-8"),
|
||
|
|
"/api/terrain" => (world.lock().unwrap().terrain_json(), "application/json"),
|
||
|
|
"/api/state" => (world.lock().unwrap().state_json(), "application/json"),
|
||
|
|
_ => {
|
||
|
|
let _ = req.respond(Response::from_string("not found").with_status_code(404));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
let header = Header::from_bytes("Content-Type", ctype).unwrap();
|
||
|
|
let _ = req.respond(Response::from_string(body).with_header(header));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|