From c4e745ba2ef02ca09def2e98db174de69921dba7 Mon Sep 17 00:00:00 2001 From: Andy Killorin <37423245+Speedy6451@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:13:56 -0600 Subject: [PATCH] scheduler api --- client/client.lua | 9 +++++++- server/src/depot.rs | 9 ++++++-- server/src/fell.rs | 12 ++++++++-- server/src/main.rs | 4 ++-- server/src/tasks.rs | 2 ++ server/src/turtle.rs | 4 ++-- server/src/turtle_api.rs | 47 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 77 insertions(+), 10 deletions(-) diff --git a/client/client.lua b/client/client.lua index 537cd08..a25c19d 100644 --- a/client/client.lua +++ b/client/client.lua @@ -195,9 +195,10 @@ repeat drawui(command, args, backoff) local ret = nil + local err = nil if command then - ret = commands[command](args) + ret, err = commands[command](args) end if command == "Update" and ret == false then @@ -212,6 +213,12 @@ repeat ret_table = "Success" else ret_table = "Failure" + term.setCursorPos(1,11) + term.clearLine() + term.setTextColor(colors.white) + term.write("error: ") + term.setTextColor(colors.red) + print(err) end elseif ret then ret_table = ret diff --git a/server/src/depot.rs b/server/src/depot.rs index f730bf3..a0590f5 100644 --- a/server/src/depot.rs +++ b/server/src/depot.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use log::warn; +use log::{warn, info}; use tokio::sync::{Mutex, OwnedMutexGuard}; use crate::{blocks::Position, turtle::TurtleCommander}; @@ -27,7 +27,7 @@ impl Depots { } pub async fn dock(&self, turtle: TurtleCommander) -> Option { - let depot = self.nearest(turtle.pos().await).await?; + let depot = self.clone().nearest(turtle.pos().await).await?; turtle.goto(*depot).await?; // dump inventory @@ -61,6 +61,11 @@ impl Depots { 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))) + } + pub fn from_vec(vec: Vec) -> Self { let mut depots = Vec::new(); for depot in vec { diff --git a/server/src/fell.rs b/server/src/fell.rs index effe6ca..cd5c284 100644 --- a/server/src/fell.rs +++ b/server/src/fell.rs @@ -22,16 +22,24 @@ pub async fn fell_tree(turtle: TurtleCommander, bottom: Vec3) -> Option<()> { const SWEEP_DELAY: usize = 16; #[derive(Serialize, Deserialize, Clone)] -struct TreeFarm { +pub struct TreeFarm { position: Vec3, size: Vec3, last_sweep: OffsetDateTime, } impl TreeFarm { + pub fn new(position: Vec3) -> Self { + Self { + position, + size: Vec3::new(5,1,2), + last_sweep: OffsetDateTime::UNIX_EPOCH, + } + } + pub async fn sweep(&self, turtle: TurtleCommander) -> Option<()> { let trees = self.size.x * self.size.y * self.size.z; - turtle.dock().await; + //turtle.dock().await; for tree in 0..trees { let index = fill(self.size, tree); let offset = index.component_mul(&Vec3::new(2, 32, 2)); diff --git a/server/src/main.rs b/server/src/main.rs index 1a7c583..56cea5a 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -115,7 +115,7 @@ async fn read_from_disk() -> anyhow::Result { let depots = match tokio::fs::OpenOptions::new() .read(true) - .open(SAVE.get().unwrap().join("turtles.json")) + .open(SAVE.get().unwrap().join("depots.json")) .await { tokio::io::Result::Ok(file) => serde_json::from_reader(file.into_std().await)?, @@ -127,7 +127,7 @@ async fn read_from_disk() -> anyhow::Result { let scheduler = match tokio::fs::OpenOptions::new() .read(true) - .open(SAVE.get().unwrap().join("scheduler.json")) + .open(SAVE.get().unwrap().join("tasks.json")) .await { tokio::io::Result::Ok(file) => serde_json::from_reader(file.into_std().await)?, diff --git a/server/src/tasks.rs b/server/src/tasks.rs index 109fa42..cb38832 100644 --- a/server/src/tasks.rs +++ b/server/src/tasks.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use erased_serde::serialize_trait_object; +use log::info; use serde::{Deserialize, Serialize}; use tokio::sync::{Mutex, MutexGuard, RwLock, OwnedMutexGuard}; use tokio::task::JoinHandle; @@ -44,6 +45,7 @@ impl Scheduler { } pub fn add_task(&mut self, task: Box) { + info!("new task"); self.tasks.push(task); } diff --git a/server/src/turtle.rs b/server/src/turtle.rs index 23fccea..8d83aa9 100644 --- a/server/src/turtle.rs +++ b/server/src/turtle.rs @@ -357,7 +357,7 @@ pub(crate) async fn process_turtle_update( let info = TurtleInfo::from_update(update, turtle.name.clone(), turtle.position.clone()); if let TurtleCommandResponse::Failure = info.ret { - warn!("{} command failure", turtle.name.to_str()); + warn!("{}: command failure", turtle.name.to_str()); } if let Some(send) = turtle.callback.take() { @@ -385,7 +385,7 @@ pub(crate) async fn process_turtle_update( } #[derive(Serialize, Deserialize, Clone, Debug)] -pub(crate) enum TurtleCommand { +pub enum TurtleCommand { Wait(u32), Forward(u32), Backward(u32), diff --git a/server/src/turtle_api.rs b/server/src/turtle_api.rs index fd385ee..2c63479 100644 --- a/server/src/turtle_api.rs +++ b/server/src/turtle_api.rs @@ -1,5 +1,6 @@ use tokio; use blocks::Vec3; +use crate::fell::TreeFarm; use crate::turtle::TurtleCommandResponse; use crate::turtle::TurtleCommander; use crate::turtle::TurtleInfo; @@ -35,7 +36,11 @@ pub fn turtle_api() -> Router { .route("/:id/dig", post(dig)) .route("/:id/cancelTask", post(cancel)) .route("/:id/manual", post(run_command)) + .route("/:id/dock", post(dock)) .route("/:id/info", get(turtle_info)) + .route("/createTreeFarm", post(fell)) + .route("/registerDepot", post(new_depot)) + .route("/pollScheduler", get(poll)) .route("/updateAll", get(update_turtles)) } @@ -73,6 +78,16 @@ pub(crate) async fn place_up( Json(response) } +pub(crate) async fn dock( + Path(id): Path, + State(state): State, +) -> Json { + let state = state.read().await; + let commander = state.get_turtle(id).await.unwrap().clone(); + drop(state); + Json(commander.dock().await.unwrap()) +} + pub(crate) async fn run_command( Path(id): Path, State(state): State, @@ -102,12 +117,42 @@ pub(crate) async fn dig( "ACK" } +pub(crate) async fn new_depot( + State(state): State, + Json(req): Json, +) -> &'static str { + let depots = &state.read().await.depots; + depots.add(req).await; + + "ACK" +} + +pub(crate) async fn poll( + State(state): State, +) -> &'static str { + let schedule = &mut state.write().await.tasks; + schedule.poll().await; + + "ACK" +} + +pub(crate) async fn fell( + State(state): State, + Json(req): Json, +) -> &'static str { + let schedule = &mut state.write().await.tasks; + schedule.add_task(Box::new(TreeFarm::new(req))); + + "ACK" +} + pub(crate) async fn set_goal( Path(id): Path, State(state): State, Json(req): Json, ) -> &'static str { - let turtle = state.read().await.get_turtle(id).await.unwrap(); + let turtle = state.read().await.get_turtle(id).await.unwrap().clone(); + drop(state); tokio::spawn(async move {turtle.goto(req).await.expect("route failed")}); "ACK"