diff --git a/server/src/main.rs b/server/src/main.rs index f41e971..420ab82 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -161,7 +161,7 @@ async fn write_to_disk(state: &LiveState) -> anyhow::Result<()> { let turtles = ron::ser::to_string_pretty(&turtles, pretty.clone())?; let world = bincode::serialize(&*state.world.clone().lock().await)?; let depots = ron::ser::to_string_pretty(&depots, pretty.clone())?; - let tasks = ron::ser::to_string_pretty(tasks, pretty.clone())?; + let tasks = ron::ser::to_string_pretty(&*tasks.lock().await, pretty.clone())?; let path = &SAVE.get().unwrap(); tokio::fs::write(path.join("turtles.ron"), turtles).await?; @@ -226,7 +226,8 @@ async fn read_from_disk(kill: watch::Sender) -> anyhow::Result }; let depots = Depots::from_vec(depots); - Ok(LiveState { turtles: bound_turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: scheduler, + Ok(LiveState { turtles: bound_turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), + tasks: Arc::new(Mutex::new(scheduler)), world: SharedWorld::from_world(world), depots, started: Instant::now(), @@ -244,7 +245,7 @@ struct SavedState { struct LiveState { turtles: Vec>>, - tasks: Scheduler, + tasks: Arc>, world: blocks::SharedWorld, depots: Depots, started: Instant, @@ -260,7 +261,7 @@ impl LiveState { }; let depots = Depots::from_vec(save.depots); - Self { turtles: turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: scheduler, world: SharedWorld::from_world(save.world), + Self { turtles: turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: Arc::new(Mutex::new(scheduler)), world: SharedWorld::from_world(save.world), depots, started: Instant::now(), kill:sender, diff --git a/server/src/turtle.rs b/server/src/turtle.rs index 3d929b6..77667ce 100644 --- a/server/src/turtle.rs +++ b/server/src/turtle.rs @@ -6,6 +6,7 @@ use crate::blocks::SharedWorld; use crate::depot::DepotGuard; use crate::depot::Depots; use crate::paths::route_facing; +use crate::tasks::Scheduler; use anyhow::Ok; @@ -156,6 +157,7 @@ pub struct TurtleCommander { max_fuel: Arc, name: Arc>, inventory: Arc>>>>, + tasks: Arc>, // this feels subpar, I feel like a mpsc would do better } impl fmt::Debug for TurtleCommander { @@ -179,6 +181,7 @@ impl TurtleCommander { name: Arc::new(OnceCell::new_with(Some(turtle.name))), depots: state.depots.clone(), inventory: Default::default(), + tasks: state.tasks.clone(), }) } @@ -192,6 +195,7 @@ impl TurtleCommander { name: Arc::new(OnceCell::new_with(Some(turtle.name))), depots: state.depots.clone(), inventory: Default::default(), + tasks: state.tasks.clone(), } } @@ -523,6 +527,10 @@ pub enum TurtleCommand { Poweroff, Refuel, CycleFront, + /// Name of the computer in front of the one commanded + NameFront, + /// Name of the current computer + Name, } #[derive(Serialize, Deserialize, Clone, Debug)] @@ -538,6 +546,7 @@ pub(crate) enum TurtleCommandResponse { Failure, Item(InventorySlot), Inventory(Vec), + Name(String), } impl TurtleCommand { diff --git a/server/src/turtle_api.rs b/server/src/turtle_api.rs index 1ade78b..17c2e2e 100644 --- a/server/src/turtle_api.rs +++ b/server/src/turtle_api.rs @@ -79,7 +79,7 @@ pub(crate) async fn register_turtle( ) -> &'static str { let state = &mut state.write().await; let commander = state.get_turtle(id).await.unwrap().clone(); - state.tasks.add_turtle(&commander); + state.tasks.lock().await.add_turtle(&commander); info!("registered turtle: {id}"); "ACK" @@ -94,7 +94,7 @@ pub(crate) async fn create_turtle( let (send, receive) = mpsc::channel(1); let turtle = turtle::Turtle::with_channel(id, Position::new(req.position, req.facing), req.fuel, req.fuellimit, send,receive); let commander = TurtleCommander::with_turtle(&turtle, state); - state.tasks.add_turtle(&commander); + state.tasks.lock().await.add_turtle(&commander); state.turtles.push( Arc::new(RwLock::new( turtle @@ -144,7 +144,8 @@ pub(crate) async fn dig( State(state): State, Json(req): Json, ) -> &'static str { - let schedule = &mut state.write().await.tasks; + let state = state.read().await; + let mut schedule = state.tasks.lock().await; let size = Vec3::new(16,16,16); schedule.add_task(Box::new(Quarry::new(req,req+size))); @@ -164,7 +165,8 @@ pub(crate) async fn new_depot( pub(crate) async fn poll( State(state): State, ) -> &'static str { - let schedule = &mut state.write().await.tasks; + let state = state.read().await; + let mut schedule = state.tasks.lock().await; schedule.poll().await; "ACK" @@ -174,9 +176,10 @@ pub(crate) async fn shutdown( State(state): State, ) -> &'static str { let signal = { - let mut state = state.write().await; - let signal = state.tasks.shutdown(); - state.tasks.poll().await; + let state = state.read().await; + let scheduler = &mut state.tasks.lock().await; + let signal = scheduler.shutdown(); + scheduler.poll().await; signal }; @@ -196,7 +199,7 @@ pub(crate) async fn fell( Json(req): Json, ) -> &'static str { let schedule = &mut state.write().await.tasks; - schedule.add_task(Box::new(TreeFarm::new(req))); + schedule.lock().await.add_task(Box::new(TreeFarm::new(req))); "ACK" } @@ -218,7 +221,7 @@ pub(crate) async fn cancel( Path(id): Path, State(state): State, ) -> &'static str { - state.write().await.tasks.cancel(Name::from_num(id)).await; + state.read().await.tasks.lock().await.cancel(Name::from_num(id)).await; "ACK" } @@ -269,7 +272,8 @@ pub(crate) async fn command( tokio::spawn(async move { let state = &state.clone(); if Instant::elapsed(&state.clone().read().await.started).as_secs_f64() > STARTUP_ALLOWANCE { - let schedule = &mut state.write().await.tasks; + let state = state.read().await; + let mut schedule = state.tasks.lock().await; trace!("idle, polling"); schedule.add_turtle(&turtle_commander.unwrap()); schedule.poll().await;