Reflection in RUST???
also implemented quarry
This commit is contained in:
parent
ebdc910a57
commit
551c472f53
3 changed files with 110 additions and 29 deletions
|
@ -1,3 +1,5 @@
|
|||
use std::sync::{Arc, atomic::{AtomicUsize, Ordering, AtomicI32}};
|
||||
|
||||
use log::{info, warn};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tokio::task::{JoinHandle, AbortHandle};
|
||||
|
@ -22,8 +24,17 @@ const VALUABLE: [&str; 1] = [
|
|||
];
|
||||
|
||||
pub async fn mine(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
|
||||
let volume = chunk.x * chunk.y * chunk.z;
|
||||
let mut pos = pos;
|
||||
|
||||
loop {
|
||||
mine_chunk_and_sweep(turtle.clone(), pos, chunk).await?;
|
||||
|
||||
pos += Vec3::z() * chunk.z;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn mine_chunk_and_sweep(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()> {
|
||||
let volume = chunk.x * chunk.y * chunk.z;
|
||||
let mut valuables = Vec::new();
|
||||
|
||||
async fn refuel_needed(turtle: &TurtleCommander, volume: i32) {
|
||||
|
@ -32,32 +43,30 @@ pub async fn mine(turtle: TurtleCommander, pos: Vec3, chunk: Vec3) -> Option<()>
|
|||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
refuel_needed(&turtle, volume).await;
|
||||
|
||||
mine_chunk(turtle.clone(), pos, chunk).await?;
|
||||
|
||||
valuables.append(&mut near_valuables(&turtle, pos, chunk).await);
|
||||
|
||||
while let Some(block) = valuables.pop() {
|
||||
if turtle.world().get(block).await.is_none() {
|
||||
continue;
|
||||
}
|
||||
let near = turtle.goto_adjacent(block).await?;
|
||||
turtle.execute(near.dig(block)?).await;
|
||||
observe(turtle.clone(), block).await;
|
||||
valuables.append(&mut near_valuables(&turtle, near.pos, Vec3::new(2,2,2)).await);
|
||||
|
||||
refuel_needed(&turtle, volume).await;
|
||||
|
||||
mine_chunk(turtle.clone(), pos, chunk).await?;
|
||||
|
||||
valuables.append(&mut near_valuables(&turtle, pos, chunk).await);
|
||||
|
||||
while let Some(block) = valuables.pop() {
|
||||
if turtle.world().get(block).await.is_none() {
|
||||
continue;
|
||||
}
|
||||
let near = turtle.goto_adjacent(block).await?;
|
||||
turtle.execute(near.dig(block)?).await;
|
||||
observe(turtle.clone(), block).await;
|
||||
valuables.append(&mut near_valuables(&turtle, near.pos, Vec3::new(2,2,2)).await);
|
||||
|
||||
refuel_needed(&turtle, volume).await;
|
||||
}
|
||||
|
||||
if dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await > 12 {
|
||||
info!("storage rtb");
|
||||
turtle.dock().await;
|
||||
}
|
||||
|
||||
pos += Vec3::z() * chunk.z;
|
||||
}
|
||||
|
||||
if dump_filter(turtle.clone(), |i| USELESS.iter().any(|u| **u == i.name)).await > 12 {
|
||||
info!("storage rtb");
|
||||
turtle.dock().await;
|
||||
}
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
async fn near_valuables(turtle: &TurtleCommander, pos: Vec3, chunk: Vec3) -> Vec<Vec3> {
|
||||
|
@ -204,3 +213,74 @@ impl Task for Mine {
|
|||
TaskState::Waiting
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize,Clone)]
|
||||
pub struct Quarry {
|
||||
pos: Vec3,
|
||||
size: Vec3,
|
||||
#[serde(skip_deserializing)]
|
||||
miners: Arc<AtomicUsize>,
|
||||
chunk: Arc<AtomicI32>
|
||||
}
|
||||
|
||||
impl Quarry {
|
||||
pub fn new(lower: Vec3, upper: Vec3) -> Self {
|
||||
let size = upper - lower;
|
||||
|
||||
Self {
|
||||
pos: lower,
|
||||
size,
|
||||
miners: Arc::new(AtomicUsize::new(0)),
|
||||
chunk: Arc::new(AtomicI32::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chunk(pos: Vec3) -> Self {
|
||||
let base = pos.map(|n| n%16);
|
||||
Self {
|
||||
pos: base,
|
||||
size: Vec3::new(16,16,16),
|
||||
miners: Arc::new(AtomicUsize::new(0)),
|
||||
chunk: Arc::new(AtomicI32::new(0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[serde]
|
||||
impl Task for Quarry {
|
||||
fn run(&mut self,turtle:TurtleCommander) -> AbortHandle {
|
||||
let chunk = self.chunk.fetch_add(1, Ordering::AcqRel);
|
||||
// TODO: partial chunks on corners
|
||||
let max_chunk = Vec3::new(4,4,4);
|
||||
let e = self.size.component_div(&max_chunk);
|
||||
|
||||
let rel_pos = fill(e, chunk).component_mul(&max_chunk);
|
||||
let abs_pos = rel_pos
|
||||
+ self.pos;
|
||||
|
||||
let owned = self.miners.clone();
|
||||
tokio::spawn(async move {
|
||||
// TODO: handle failure
|
||||
// another turtle should get the next chunk while this is in flight, but program
|
||||
// termination or a None return should reschedule the chunk
|
||||
mine_chunk_and_sweep(turtle, abs_pos, max_chunk).await.unwrap();
|
||||
owned.fetch_sub(1, Ordering::AcqRel);
|
||||
}).abort_handle()
|
||||
}
|
||||
|
||||
fn poll(&mut self) -> TaskState {
|
||||
let only = self.miners.fetch_update(Ordering::AcqRel, Ordering::Acquire, |n| {
|
||||
if n < 1 {
|
||||
Some(n+1)
|
||||
}else {
|
||||
None
|
||||
}
|
||||
}).is_ok();
|
||||
|
||||
if only {
|
||||
// This is approximate as we have to go to a depot anyway
|
||||
return TaskState::Ready(Position::new(self.pos, Direction::North));
|
||||
}
|
||||
TaskState::Waiting
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ impl Scheduler {
|
|||
}
|
||||
|
||||
pub fn add_task(&mut self, task: Box<dyn Task>) {
|
||||
trace!("new task");
|
||||
trace!("new {} task", task.typetag_name());
|
||||
self.tasks.push(task);
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ impl Scheduler {
|
|||
None => break,
|
||||
};
|
||||
|
||||
trace!("scheduling task on #{}", closest_turtle.0.name().to_num());
|
||||
trace!("scheduling {} on #{}", task.typetag_name(), closest_turtle.0.name().to_num());
|
||||
closest_turtle.1 = Some(task.run(closest_turtle.0.clone()));
|
||||
}
|
||||
if let TaskState::Complete = poll {
|
||||
|
|
|
@ -4,6 +4,7 @@ use blocks::Vec3;
|
|||
use tokio::time::Instant;
|
||||
use crate::fell::TreeFarm;
|
||||
use crate::mine::Mine;
|
||||
use crate::mine::Quarry;
|
||||
use crate::turtle::IDLE_TIME;
|
||||
use crate::turtle::TurtleCommandResponse;
|
||||
use crate::turtle::TurtleCommander;
|
||||
|
@ -112,8 +113,8 @@ pub(crate) async fn dig(
|
|||
Json(req): Json<Vec3>,
|
||||
) -> &'static str {
|
||||
let schedule = &mut state.write().await.tasks;
|
||||
let chunk = Vec3::new(4,4,4);
|
||||
schedule.add_task(Box::new(Mine::new(req,chunk)));
|
||||
let size = Vec3::new(16,16,16);
|
||||
schedule.add_task(Box::new(Quarry::new(req,req+size)));
|
||||
|
||||
"ACK"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue