From ea37afe9ae9a1607fa3b6f365b9307c579c45b8d Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 11 Jun 2022 16:33:15 +0200 Subject: savestating --- karld/src/main.rs | 8 +++++++- karld/src/savestate.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 karld/src/savestate.rs diff --git a/karld/src/main.rs b/karld/src/main.rs index 2d0c9e9..181c2be 100644 --- a/karld/src/main.rs +++ b/karld/src/main.rs @@ -1,6 +1,7 @@ pub mod condition; pub mod helper; pub mod interface; +pub mod savestate; pub mod schedule; use chrono::NaiveDateTime; @@ -11,12 +12,15 @@ use interface::network_loop; use karlcommon::{ ClientboundPacket, Condition, Instance, Property, ProtoError, Schedule, ServerboundPacket, Task, }; -use log::{debug, info}; +use log::{debug, error, info}; use std::{collections::HashMap, sync::RwLock}; fn main() { env_logger::init(); info!("logging"); + if let Err(e) = savestate::load() { + error!("load failed: {}", e); + } TASKS.write().unwrap().insert( 0, Task { @@ -88,11 +92,13 @@ pub fn handle_packet(client: u32, packet: ServerboundPacket, responder: Sender { TASKS.write().unwrap().insert(t.id, t); + savestate::save(); } ServerboundPacket::RemoveTask(i) => { if TASKS.write().unwrap().remove(&i).is_none() { let _ = responder.send(ClientboundPacket::Error(ProtoError::UnknownTask)); } + savestate::save(); } ServerboundPacket::Handshake { version } => { debug!("{client}: version {version}"); diff --git a/karld/src/savestate.rs b/karld/src/savestate.rs new file mode 100644 index 0000000..a97528c --- /dev/null +++ b/karld/src/savestate.rs @@ -0,0 +1,50 @@ +use karlcommon::Task; +use log::{error, info}; + +use crate::TASKS; +use std::{ + collections::BTreeMap, + fs::{create_dir_all, File}, + io, + path::{Path, PathBuf}, +}; + +fn save_dir() -> PathBuf { + std::env::var("XDG_DATA_HOME") + .map(|p| Path::new(p.as_str()).to_path_buf()) + .unwrap_or_else(|_| { + Path::new(&std::env::var("HOME").expect("$HOME needs to be set")) + .to_path_buf() + .join(".local") + .join("share") + }) + .join("karl") +} + +pub fn save() { + if let Err(r) = save_inner() { + error!("save failed: {}", r); + } +} + +pub fn save_inner() -> io::Result<()> { + info!("saving..."); + create_dir_all(save_dir())?; + let file = File::create(save_dir().join("tasks"))?; + serde_json::to_writer(file, &TASKS.read().unwrap().to_owned())?; + info!("done"); + Ok(()) +} + +pub fn load() -> io::Result<()> { + info!("loading savestate..."); + let file = File::open(save_dir().join("tasks"))?; + let tasks: BTreeMap = serde_json::from_reader(file)?; + + let mut guard = TASKS.write().unwrap(); + guard.clear(); + guard.extend(tasks.into_iter()); + info!("done"); + + Ok(()) +} -- cgit v1.2.3-70-g09d2