depot semaphore
This commit is contained in:
parent
9859f64d65
commit
42ef46f2ff
3 changed files with 26 additions and 11 deletions
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use tracing::{warn, info, trace};
|
use tracing::{warn, info, trace};
|
||||||
use tokio::sync::{Mutex, OwnedMutexGuard};
|
use tokio::sync::{Mutex, OwnedMutexGuard, Semaphore};
|
||||||
|
|
||||||
use crate::{blocks::Position, turtle::TurtleCommander};
|
use crate::{blocks::Position, turtle::TurtleCommander};
|
||||||
use crate::turtle::{TurtleCommand::*, TurtleCommandResponse};
|
use crate::turtle::{TurtleCommand::*, TurtleCommandResponse};
|
||||||
|
@ -13,7 +13,8 @@ use crate::turtle::{TurtleCommand::*, TurtleCommandResponse};
|
||||||
/// ahead of the specified position is a chest of combustibles
|
/// ahead of the specified position is a chest of combustibles
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Depots {
|
pub struct Depots {
|
||||||
depots: Arc<Mutex<Vec<Arc<Mutex<Position>>>>>
|
depots: Arc<Mutex<Vec<Arc<Mutex<Position>>>>>,
|
||||||
|
depot_semaphore: Arc<Semaphore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Depots {
|
impl Depots {
|
||||||
|
@ -27,6 +28,7 @@ impl Depots {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn dock(&self, turtle: TurtleCommander) -> Option<usize> {
|
pub async fn dock(&self, turtle: TurtleCommander) -> Option<usize> {
|
||||||
|
let permit = self.depot_semaphore.clone().acquire_owned().await.unwrap();
|
||||||
let depot = self.clone().nearest(turtle.pos().await).await?;
|
let depot = self.clone().nearest(turtle.pos().await).await?;
|
||||||
trace!("depot at {depot:?}");
|
trace!("depot at {depot:?}");
|
||||||
turtle.goto(*depot).await?;
|
turtle.goto(*depot).await?;
|
||||||
|
@ -55,22 +57,26 @@ 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
|
// lava bucket fix
|
||||||
for i in 1..=16 {
|
for i in 1..=16 {
|
||||||
turtle.execute(Select(i)).await;
|
turtle.execute(Select(i)).await;
|
||||||
turtle.execute(DropDown(64)).await;
|
turtle.execute(DropDown(64)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
turtle.execute(Backward(1)).await;
|
|
||||||
|
|
||||||
drop(depot); // assumes that the turtle will very quickly leave
|
|
||||||
|
|
||||||
Some(turtle.fuel())
|
Some(turtle.fuel())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add(&self, pos: Position) {
|
pub async fn add(&self, pos: Position) {
|
||||||
info!("new depot at {pos:?}");
|
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<Position>) -> Self {
|
pub fn from_vec(vec: Vec<Position>) -> Self {
|
||||||
|
@ -78,7 +84,10 @@ impl Depots {
|
||||||
for depot in vec {
|
for depot in vec {
|
||||||
depots.push(Arc::new(Mutex::new(depot)));
|
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<Position> {
|
pub async fn to_vec(self) -> Vec<Position> {
|
||||||
|
|
|
@ -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<Vec3> {
|
async fn near_valuables(turtle: &TurtleCommander, pos: Vec3, chunk: Vec3) -> Vec<Vec3> {
|
||||||
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;
|
let world = turtle.world().lock().await;
|
||||||
scan.map(|n| world.get(n))
|
scan.map(|n| world.get(n))
|
||||||
|
|
|
@ -348,10 +348,16 @@ pub(crate) async fn process_turtle_update(
|
||||||
state: &LiveState,
|
state: &LiveState,
|
||||||
update: TurtleUpdate,
|
update: TurtleUpdate,
|
||||||
) -> Option<TurtleCommand> {
|
) -> Option<TurtleCommand> {
|
||||||
let mut turtle = state
|
let mut turtle = match state
|
||||||
.turtles
|
.turtles
|
||||||
.get(id as usize)
|
.get(id as usize) {
|
||||||
.context("nonexisting turtle").unwrap().write().await;
|
Some(turtle) => turtle.write().await,
|
||||||
|
None => {
|
||||||
|
error!("nonexisting turtle {id}");
|
||||||
|
return Some(TurtleCommand::Poweroff);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let world = &state.world;
|
let world = &state.world;
|
||||||
|
|
||||||
if turtle.pending_update {
|
if turtle.pending_update {
|
||||||
|
|
Loading…
Reference in a new issue