From 42ef46f2ff2b536fd74723a0177dbb53c009a532 Mon Sep 17 00:00:00 2001 From: Andy Killorin <37423245+Speedy6451@users.noreply.github.com> Date: Tue, 26 Dec 2023 09:14:28 -0600 Subject: [PATCH] depot semaphore --- server/src/depot.rs | 23 ++++++++++++++++------- server/src/mine.rs | 2 +- server/src/turtle.rs | 12 +++++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/server/src/depot.rs b/server/src/depot.rs index 5d3b1ff..d45b81f 100644 --- a/server/src/depot.rs +++ b/server/src/depot.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use tracing::{warn, info, trace}; -use tokio::sync::{Mutex, OwnedMutexGuard}; +use tokio::sync::{Mutex, OwnedMutexGuard, Semaphore}; use crate::{blocks::Position, turtle::TurtleCommander}; use crate::turtle::{TurtleCommand::*, TurtleCommandResponse}; @@ -13,7 +13,8 @@ use crate::turtle::{TurtleCommand::*, TurtleCommandResponse}; /// ahead of the specified position is a chest of combustibles #[derive(Clone, Debug)] pub struct Depots { - depots: Arc>>>> + depots: Arc>>>>, + depot_semaphore: Arc, } impl Depots { @@ -27,6 +28,7 @@ impl Depots { } pub async fn dock(&self, turtle: TurtleCommander) -> Option { + let permit = self.depot_semaphore.clone().acquire_owned().await.unwrap(); let depot = self.clone().nearest(turtle.pos().await).await?; trace!("depot at {depot:?}"); turtle.goto(*depot).await?; @@ -54,23 +56,27 @@ impl Depots { } } } + + // This can fail, we don't really care (as long as it executes once) + turtle.execute(Backward(4)).await; + + drop(depot); + drop(permit); // lava bucket fix for i in 1..=16 { turtle.execute(Select(i)).await; turtle.execute(DropDown(64)).await; } - - turtle.execute(Backward(1)).await; - drop(depot); // assumes that the turtle will very quickly leave Some(turtle.fuel()) } pub async fn add(&self, pos: Position) { info!("new depot at {pos:?}"); - self.depots.lock().await.push(Arc::new(Mutex::new(pos))) + self.depots.lock().await.push(Arc::new(Mutex::new(pos))); + self.depot_semaphore.add_permits(1); } pub fn from_vec(vec: Vec) -> Self { @@ -78,7 +84,10 @@ impl Depots { for depot in vec { depots.push(Arc::new(Mutex::new(depot))); } - Depots { depots: Arc::new(Mutex::new(depots)) } + let permits = depots.len(); + Depots { depots: Arc::new(Mutex::new(depots)), + depot_semaphore: Arc::new(Semaphore::new(permits)) + } } pub async fn to_vec(self) -> Vec { diff --git a/server/src/mine.rs b/server/src/mine.rs index 27377cd..589c62d 100644 --- a/server/src/mine.rs +++ b/server/src/mine.rs @@ -71,7 +71,7 @@ pub async fn mine_chunk_and_sweep(turtle: TurtleCommander, pos: Vec3, chunk: Vec } async fn near_valuables(turtle: &TurtleCommander, pos: Vec3, chunk: Vec3) -> Vec { - let scan = (0..=(chunk*2).product()).map(|n| fill(chunk * 2, n) - chunk/2); + let scan = (0..(chunk*2).product()).map(|n| fill(chunk * 2, n) - chunk/2); let world = turtle.world().lock().await; scan.map(|n| world.get(n)) diff --git a/server/src/turtle.rs b/server/src/turtle.rs index 066777c..94bc33b 100644 --- a/server/src/turtle.rs +++ b/server/src/turtle.rs @@ -348,10 +348,16 @@ pub(crate) async fn process_turtle_update( state: &LiveState, update: TurtleUpdate, ) -> Option { - let mut turtle = state + let mut turtle = match state .turtles - .get(id as usize) - .context("nonexisting turtle").unwrap().write().await; + .get(id as usize) { + Some(turtle) => turtle.write().await, + None => { + error!("nonexisting turtle {id}"); + return Some(TurtleCommand::Poweroff); + }, + }; + let world = &state.world; if turtle.pending_update {