From ec40f6e3acc7874b82709ab81b254c741529fdff Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 26 Oct 2026 10:52:04 -0400 Subject: Finish engine --- platforms/tortuise-script-compiled/src/storage.rs | 181 ++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 platforms/tortuise-script-compiled/src/storage.rs (limited to 'platforms/tortuise-script-compiled/src/storage.rs') diff --git a/platforms/tortuise-script-compiled/src/storage.rs b/platforms/tortuise-script-compiled/src/storage.rs new file mode 100644 index 0000000..d028a91 --- /dev/null +++ b/platforms/tortuise-script-compiled/src/storage.rs @@ -0,0 +1,181 @@ +use core::ops::{Deref, DerefMut}; + +use serde::{Serialize, de::DeserializeOwned}; +use spin::Mutex; +use tortuise::script::Operation; + +use crate::ScriptContext; + +pub struct Storage { + initial_state: fn() -> T, + data: Mutex>, +} + +pub struct Config { + initial_state: fn() -> T, + data: Mutex>, +} + +pub struct StorageMut<'a, 'cx, T: Serialize + Eq> { + context: &'cx mut ScriptContext<'a>, + data: T, + original: T, +} + +pub struct ConfigMut<'a, 'cx, T: Serialize + Eq> { + context: &'cx mut ScriptContext<'a>, + data: T, + original: T, +} + +impl Storage { + pub const fn new(initial_state: fn() -> T) -> Self { + Self { + initial_state, + data: Mutex::new(None), + } + } + + pub fn load(&self, context: &ScriptContext) -> T { + puffin::profile_function!(); + let mut data = self.data.lock(); + data.get_or_insert_with(|| { + context + .0 + .storage + .data() + .map(messagepack_serde::from_slice) + .and_then(|r| r.ok()) + .unwrap_or_else(self.initial_state) + }) + .clone() + } + + pub fn load_mut<'a, 'cx>(&self, context: &'cx mut ScriptContext<'a>) -> StorageMut<'a, 'cx, T> { + let data = self.load(context); + StorageMut { + original: data.clone(), + data, + context, + } + } + + pub fn is_saving(&self, context: &ScriptContext) -> bool { + context.0.storage.is_saving_data() + } + + pub fn save_failed(&self, context: &ScriptContext) -> bool { + context.0.storage.saving_data_failed() + } +} + +impl Config { + pub const fn new(initial_state: fn() -> T) -> Self { + Self { + initial_state, + data: Mutex::new(None), + } + } + + pub fn load(&self, context: &ScriptContext) -> T { + puffin::profile_function!(); + let mut data = self.data.lock(); + data.get_or_insert_with(|| { + context + .0 + .storage + .config() + .map(toml::from_slice) + .and_then(|r| r.ok()) + .unwrap_or_else(self.initial_state) + }) + .clone() + } + + pub fn load_mut<'a, 'cx>(&self, context: &'cx mut ScriptContext<'a>) -> StorageMut<'a, 'cx, T> { + let data = self.load(context); + StorageMut { + original: data.clone(), + data, + context, + } + } + + pub fn is_saving(&self, context: &ScriptContext) -> bool { + context.0.storage.is_saving_config() + } + + pub fn save_failed(&self, context: &ScriptContext) -> bool { + context.0.storage.saving_config_failed() + } +} + +impl Deref for StorageMut<'_, '_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl DerefMut for StorageMut<'_, '_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} + +impl Drop for StorageMut<'_, '_, T> { + fn drop(&mut self) { + puffin::profile_function!(); + if self.data == self.original { + return; + } + + let new_save = match messagepack_serde::to_vec(&self.data) { + Ok(new_save) => new_save.into_boxed_slice(), + Err(e) => { + log::error!("{e}"); + return; + } + }; + self.context + .0 + .operation_queue + .push(Operation::UpdateStorage { new_save }); + } +} + +impl Deref for ConfigMut<'_, '_, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl DerefMut for ConfigMut<'_, '_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} + +impl Drop for ConfigMut<'_, '_, T> { + fn drop(&mut self) { + puffin::profile_function!(); + if self.data == self.original { + return; + } + + let new_save = match toml::to_string(&self.data) { + Ok(new_save) => new_save.as_bytes().into(), + Err(e) => { + log::error!("{e}"); + return; + } + }; + self.context + .0 + .operation_queue + .push(Operation::UpdateConfig { new_save }); + } +} -- cgit v1.3.1