clonable scheduler (ick)
This commit is contained in:
parent
1d98390c8d
commit
e4b7da9527
3 changed files with 28 additions and 14 deletions
|
@ -161,7 +161,7 @@ async fn write_to_disk(state: &LiveState) -> anyhow::Result<()> {
|
||||||
let turtles = ron::ser::to_string_pretty(&turtles, pretty.clone())?;
|
let turtles = ron::ser::to_string_pretty(&turtles, pretty.clone())?;
|
||||||
let world = bincode::serialize(&*state.world.clone().lock().await)?;
|
let world = bincode::serialize(&*state.world.clone().lock().await)?;
|
||||||
let depots = ron::ser::to_string_pretty(&depots, pretty.clone())?;
|
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();
|
let path = &SAVE.get().unwrap();
|
||||||
tokio::fs::write(path.join("turtles.ron"), turtles).await?;
|
tokio::fs::write(path.join("turtles.ron"), turtles).await?;
|
||||||
|
@ -226,7 +226,8 @@ async fn read_from_disk(kill: watch::Sender<bool>) -> anyhow::Result<LiveState>
|
||||||
};
|
};
|
||||||
let depots = Depots::from_vec(depots);
|
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),
|
world: SharedWorld::from_world(world),
|
||||||
depots,
|
depots,
|
||||||
started: Instant::now(),
|
started: Instant::now(),
|
||||||
|
@ -244,7 +245,7 @@ struct SavedState {
|
||||||
|
|
||||||
struct LiveState {
|
struct LiveState {
|
||||||
turtles: Vec<Arc<RwLock<turtle::Turtle>>>,
|
turtles: Vec<Arc<RwLock<turtle::Turtle>>>,
|
||||||
tasks: Scheduler,
|
tasks: Arc<Mutex<Scheduler>>,
|
||||||
world: blocks::SharedWorld,
|
world: blocks::SharedWorld,
|
||||||
depots: Depots,
|
depots: Depots,
|
||||||
started: Instant,
|
started: Instant,
|
||||||
|
@ -260,7 +261,7 @@ impl LiveState {
|
||||||
};
|
};
|
||||||
let depots = Depots::from_vec(save.depots);
|
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,
|
depots,
|
||||||
started: Instant::now(),
|
started: Instant::now(),
|
||||||
kill:sender,
|
kill:sender,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::blocks::SharedWorld;
|
||||||
use crate::depot::DepotGuard;
|
use crate::depot::DepotGuard;
|
||||||
use crate::depot::Depots;
|
use crate::depot::Depots;
|
||||||
use crate::paths::route_facing;
|
use crate::paths::route_facing;
|
||||||
|
use crate::tasks::Scheduler;
|
||||||
|
|
||||||
use anyhow::Ok;
|
use anyhow::Ok;
|
||||||
|
|
||||||
|
@ -156,6 +157,7 @@ pub struct TurtleCommander {
|
||||||
max_fuel: Arc<AtomicUsize>,
|
max_fuel: Arc<AtomicUsize>,
|
||||||
name: Arc<OnceCell<Name>>,
|
name: Arc<OnceCell<Name>>,
|
||||||
inventory: Arc<RwLock<Option<Vec<Option<InventorySlot>>>>>,
|
inventory: Arc<RwLock<Option<Vec<Option<InventorySlot>>>>>,
|
||||||
|
tasks: Arc<Mutex<Scheduler>>, // this feels subpar, I feel like a mpsc would do better
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for TurtleCommander {
|
impl fmt::Debug for TurtleCommander {
|
||||||
|
@ -179,6 +181,7 @@ impl TurtleCommander {
|
||||||
name: Arc::new(OnceCell::new_with(Some(turtle.name))),
|
name: Arc::new(OnceCell::new_with(Some(turtle.name))),
|
||||||
depots: state.depots.clone(),
|
depots: state.depots.clone(),
|
||||||
inventory: Default::default(),
|
inventory: Default::default(),
|
||||||
|
tasks: state.tasks.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +195,7 @@ impl TurtleCommander {
|
||||||
name: Arc::new(OnceCell::new_with(Some(turtle.name))),
|
name: Arc::new(OnceCell::new_with(Some(turtle.name))),
|
||||||
depots: state.depots.clone(),
|
depots: state.depots.clone(),
|
||||||
inventory: Default::default(),
|
inventory: Default::default(),
|
||||||
|
tasks: state.tasks.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +527,10 @@ pub enum TurtleCommand {
|
||||||
Poweroff,
|
Poweroff,
|
||||||
Refuel,
|
Refuel,
|
||||||
CycleFront,
|
CycleFront,
|
||||||
|
/// Name of the computer in front of the one commanded
|
||||||
|
NameFront,
|
||||||
|
/// Name of the current computer
|
||||||
|
Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
@ -538,6 +546,7 @@ pub(crate) enum TurtleCommandResponse {
|
||||||
Failure,
|
Failure,
|
||||||
Item(InventorySlot),
|
Item(InventorySlot),
|
||||||
Inventory(Vec<InventorySlot>),
|
Inventory(Vec<InventorySlot>),
|
||||||
|
Name(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TurtleCommand {
|
impl TurtleCommand {
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) async fn register_turtle(
|
||||||
) -> &'static str {
|
) -> &'static str {
|
||||||
let state = &mut state.write().await;
|
let state = &mut state.write().await;
|
||||||
let commander = state.get_turtle(id).await.unwrap().clone();
|
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}");
|
info!("registered turtle: {id}");
|
||||||
|
|
||||||
"ACK"
|
"ACK"
|
||||||
|
@ -94,7 +94,7 @@ pub(crate) async fn create_turtle(
|
||||||
let (send, receive) = mpsc::channel(1);
|
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 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);
|
let commander = TurtleCommander::with_turtle(&turtle, state);
|
||||||
state.tasks.add_turtle(&commander);
|
state.tasks.lock().await.add_turtle(&commander);
|
||||||
state.turtles.push(
|
state.turtles.push(
|
||||||
Arc::new(RwLock::new(
|
Arc::new(RwLock::new(
|
||||||
turtle
|
turtle
|
||||||
|
@ -144,7 +144,8 @@ pub(crate) async fn dig(
|
||||||
State(state): State<SharedControl>,
|
State(state): State<SharedControl>,
|
||||||
Json(req): Json<Vec3>,
|
Json(req): Json<Vec3>,
|
||||||
) -> &'static str {
|
) -> &'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);
|
let size = Vec3::new(16,16,16);
|
||||||
schedule.add_task(Box::new(Quarry::new(req,req+size)));
|
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(
|
pub(crate) async fn poll(
|
||||||
State(state): State<SharedControl>,
|
State(state): State<SharedControl>,
|
||||||
) -> &'static str {
|
) -> &'static str {
|
||||||
let schedule = &mut state.write().await.tasks;
|
let state = state.read().await;
|
||||||
|
let mut schedule = state.tasks.lock().await;
|
||||||
schedule.poll().await;
|
schedule.poll().await;
|
||||||
|
|
||||||
"ACK"
|
"ACK"
|
||||||
|
@ -174,9 +176,10 @@ pub(crate) async fn shutdown(
|
||||||
State(state): State<SharedControl>,
|
State(state): State<SharedControl>,
|
||||||
) -> &'static str {
|
) -> &'static str {
|
||||||
let signal = {
|
let signal = {
|
||||||
let mut state = state.write().await;
|
let state = state.read().await;
|
||||||
let signal = state.tasks.shutdown();
|
let scheduler = &mut state.tasks.lock().await;
|
||||||
state.tasks.poll().await;
|
let signal = scheduler.shutdown();
|
||||||
|
scheduler.poll().await;
|
||||||
signal
|
signal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -196,7 +199,7 @@ pub(crate) async fn fell(
|
||||||
Json(req): Json<Vec3>,
|
Json(req): Json<Vec3>,
|
||||||
) -> &'static str {
|
) -> &'static str {
|
||||||
let schedule = &mut state.write().await.tasks;
|
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"
|
"ACK"
|
||||||
}
|
}
|
||||||
|
@ -218,7 +221,7 @@ pub(crate) async fn cancel(
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
State(state): State<SharedControl>,
|
State(state): State<SharedControl>,
|
||||||
) -> &'static str {
|
) -> &'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"
|
"ACK"
|
||||||
}
|
}
|
||||||
|
@ -269,7 +272,8 @@ pub(crate) async fn command(
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let state = &state.clone();
|
let state = &state.clone();
|
||||||
if Instant::elapsed(&state.clone().read().await.started).as_secs_f64() > STARTUP_ALLOWANCE {
|
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");
|
trace!("idle, polling");
|
||||||
schedule.add_turtle(&turtle_commander.unwrap());
|
schedule.add_turtle(&turtle_commander.unwrap());
|
||||||
schedule.poll().await;
|
schedule.poll().await;
|
||||||
|
|
Loading…
Reference in a new issue