Path: blob/main/crates/bevy_settings/src/store_wasm.rs
30620 views
use bevy_log::error;1use bevy_tasks::IoTaskPool;2use web_sys::window;34/// Persistent storage which uses browser local storage.5pub(crate) struct PreferencesStore {6app_name: String,7}89impl PreferencesStore {10/// Construct a new preferences store for browser local storage.11///12/// # Arguments13/// * `app_name` - The name of the application. See [`crate::PreferencesPlugin`] for usage.14pub fn new(app_name: &str) -> Self {15Self {16app_name: app_name.to_owned(),17}18}1920/// Returns the storage key for a given filename. This consists of the app name combined21/// with the filename.22fn storage_key(&self, filename: &str) -> String {23format!("{}-{}", self.app_name, filename)24}2526/// Save a [`toml::Table`] to browser storage, synchronously.27///28/// # Arguments29/// * `filename` - the name of the file to be saved30/// * `contents` - the contents of the file31pub(crate) fn save(&self, filename: &str, contents: toml::Table) {32if let Ok(Some(storage)) = window().unwrap().local_storage() {33let toml_str = contents.to_string();34storage35.set_item(self.storage_key(filename).as_str(), &toml_str)36.unwrap();37}38}3940/// Save the content of a [`toml::Table`] to local storage, in another thread.41///42/// # Arguments43/// * `filename` - the name of the file to be saved44/// * `contents` - the contents of the file45pub(crate) fn save_async(&self, filename: &str, contents: toml::Table) {46IoTaskPool::get().scope(|scope| {47scope.spawn(async {48if let Ok(Some(storage)) = window().unwrap().local_storage() {49let toml_str = contents.to_string();50storage51.set_item(self.storage_key(filename).as_str(), &toml_str)52.unwrap();53}54});55});56}5758/// Deserialize a [`toml::Table`]. If the file does not exist, `None` will59/// be returned.60///61/// # Arguments62/// * `filename` - The name of the preferences file, without the file extension.63pub(crate) fn load(&self, filename: &str) -> Option<toml::Table> {64if let Ok(Some(storage)) = window().unwrap().local_storage() {65let storage_key = self.storage_key(filename);66let Ok(Some(toml_str)) = storage.get_item(&storage_key) else {67return None;68};6970let table_value = match toml::from_str::<toml::Value>(&toml_str) {71Ok(table_value) => table_value,72Err(e) => {73error!("Error parsing preferences file: {}", e);74return None;75}76};7778match table_value {79toml::Value::Table(table) => Some(table),80_ => {81error!("Preferences file must be a table");82None83}84}85} else {86None87}88}89}909192