diff --git a/server/Cargo.toml b/server/Cargo.toml index 629de4b..78550ed 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" axum = "0.7.2" +bincode = "1.3.3" bit-struct = "0.3.2" const_format = "0.2.32" erased-serde = "0.4.1" diff --git a/server/Makefile b/server/Makefile index e33165d..257cef3 100644 --- a/server/Makefile +++ b/server/Makefile @@ -1,13 +1,14 @@ -DEVPORT=1505 -DEVFILE="offline-state.json" +DEVPORT=1507 +DEVFILE="dev" PRODPORT=48228 -PRODFILE="state.json" +PRODFILE="prod" MANIFEST=../Cargo.toml .PHONY: local global local: surnames.txt names.txt ipaddr.txt echo '"localhost"' > ipaddr.txt + mkdir -p dev cargo run $(DEVPORT) $(DEVFILE) global: surnames.txt names.txt ipaddr.txt diff --git a/server/src/main.rs b/server/src/main.rs index 86f3fed..d6107e8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,6 +1,6 @@ #![feature(iter_map_windows)] -use std::{collections::VecDeque, io::ErrorKind, sync::Arc, env::args}; +use std::{collections::VecDeque, io::ErrorKind, sync::Arc, env::args, path}; use anyhow::{Context, Error, Ok}; use axum::{ @@ -73,7 +73,7 @@ impl LiveState { } static PORT: OnceCell = OnceCell::const_new(); -static SAVE: OnceCell = OnceCell::const_new(); +static SAVE: OnceCell = OnceCell::const_new(); type SharedControl = Arc>; @@ -85,24 +85,11 @@ async fn main() -> Result<(), Error> { None => 48228, })?; SAVE.set(match args.next() { - Some(file) => file, - None => "state.json".to_string(), + Some(file) => file.into(), + None => "save".into(), })?; - let state = match tokio::fs::OpenOptions::new() - .read(true) - .open(SAVE.get().unwrap()) - .await - { - tokio::io::Result::Ok(file) => serde_json::from_reader(file.into_std().await)?, - tokio::io::Result::Err(e) => match e.kind() { - ErrorKind::NotFound => SavedState { - turtles: Vec::new(), - world: RTree::new(), - }, - _ => panic!(), - }, - }; + let state = read_from_disk().await?; let state = LiveState::from_save(state); @@ -142,11 +129,42 @@ async fn flush(State(state): State) -> &'static str { } async fn write_to_disk(state: SavedState) -> anyhow::Result<()> { - let json = serde_json::to_string_pretty(&state)?; - tokio::fs::write(SAVE.get().unwrap(), json).await?; + let json = serde_json::to_string_pretty(&state.turtles)?; + let bincode = bincode::serialize(&state.world)?; + tokio::fs::write(SAVE.get().unwrap().join("turtles.json"), json).await?; + tokio::fs::write(SAVE.get().unwrap().join("world.bin"), bincode).await?; Ok(()) } +async fn read_from_disk() -> anyhow::Result { + let turtles = match tokio::fs::OpenOptions::new() + .read(true) + .open(SAVE.get().unwrap().join("turtles.json")) + .await + { + tokio::io::Result::Ok(file) => serde_json::from_reader(file.into_std().await)?, + tokio::io::Result::Err(e) => match e.kind() { + ErrorKind::NotFound => Vec::new(), + _ => panic!(), + }, + }; + + let world = match tokio::fs::OpenOptions::new() + .read(true).open(SAVE.get().unwrap().join("world.bin")).await { + tokio::io::Result::Ok(file) => bincode::deserialize_from(file.into_std().await)?, + tokio::io::Result::Err(e) => match e.kind() { + ErrorKind::NotFound => RTree::new(), + _ => panic!(), + }, + + }; + + Ok(SavedState { + turtles, + world, + }) +} + async fn create_turtle( State(state): State, Json(req): Json, diff --git a/server/src/turtle.rs b/server/src/turtle.rs index 1cd12db..e9a21ee 100644 --- a/server/src/turtle.rs +++ b/server/src/turtle.rs @@ -274,7 +274,8 @@ impl TurtleCommander { if let TurtleCommandResponse::Failure = state.ret { if let TurtleCommand::Backward(_) = command { // turn around if you bump your rear on something - self.goto(Position::new(recent.pos, recent.dir.left().left())).await? + self.execute(TurtleCommand::Left).await; + recent = self.execute(TurtleCommand::Left).await.pos; } break 'route; } @@ -305,13 +306,13 @@ pub(crate) async fn process_turtle_update( if turtle.fuel > update.fuel { let diff = turtle.fuel - update.fuel; - turtle.fuel = update.fuel; let delta = turtle.queued_movement * diff as i32; turtle.position.pos += delta; turtle.queued_movement = Vec3::zeros(); } + turtle.fuel = update.fuel; let above = Block { name: update.above.clone(),