aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <yvchraiqi@protonmail.com>2022-06-11 16:33:15 +0200
committermetamuffin <yvchraiqi@protonmail.com>2022-06-11 16:33:15 +0200
commitea37afe9ae9a1607fa3b6f365b9307c579c45b8d (patch)
tree4e64754887dcd666a54d0f17d4964c5aecf36334
parent62836238f63688b45760929bdc2715f8f9991f2f (diff)
downloadkarlender-ea37afe9ae9a1607fa3b6f365b9307c579c45b8d.tar
karlender-ea37afe9ae9a1607fa3b6f365b9307c579c45b8d.tar.bz2
karlender-ea37afe9ae9a1607fa3b6f365b9307c579c45b8d.tar.zst
savestating
-rw-r--r--karld/src/main.rs8
-rw-r--r--karld/src/savestate.rs50
2 files changed, 57 insertions, 1 deletions
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<C
}
ServerboundPacket::UpdateTask(t) => {
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<u64, Task> = serde_json::from_reader(file)?;
+
+ let mut guard = TASKS.write().unwrap();
+ guard.clear();
+ guard.extend(tasks.into_iter());
+ info!("done");
+
+ Ok(())
+}