Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_settings/src/store_wasm.rs
30620 views
1
use bevy_log::error;
2
use bevy_tasks::IoTaskPool;
3
use web_sys::window;
4
5
/// Persistent storage which uses browser local storage.
6
pub(crate) struct PreferencesStore {
7
app_name: String,
8
}
9
10
impl PreferencesStore {
11
/// Construct a new preferences store for browser local storage.
12
///
13
/// # Arguments
14
/// * `app_name` - The name of the application. See [`crate::PreferencesPlugin`] for usage.
15
pub fn new(app_name: &str) -> Self {
16
Self {
17
app_name: app_name.to_owned(),
18
}
19
}
20
21
/// Returns the storage key for a given filename. This consists of the app name combined
22
/// with the filename.
23
fn storage_key(&self, filename: &str) -> String {
24
format!("{}-{}", self.app_name, filename)
25
}
26
27
/// Save a [`toml::Table`] to browser storage, synchronously.
28
///
29
/// # Arguments
30
/// * `filename` - the name of the file to be saved
31
/// * `contents` - the contents of the file
32
pub(crate) fn save(&self, filename: &str, contents: toml::Table) {
33
if let Ok(Some(storage)) = window().unwrap().local_storage() {
34
let toml_str = contents.to_string();
35
storage
36
.set_item(self.storage_key(filename).as_str(), &toml_str)
37
.unwrap();
38
}
39
}
40
41
/// Save the content of a [`toml::Table`] to local storage, in another thread.
42
///
43
/// # Arguments
44
/// * `filename` - the name of the file to be saved
45
/// * `contents` - the contents of the file
46
pub(crate) fn save_async(&self, filename: &str, contents: toml::Table) {
47
IoTaskPool::get().scope(|scope| {
48
scope.spawn(async {
49
if let Ok(Some(storage)) = window().unwrap().local_storage() {
50
let toml_str = contents.to_string();
51
storage
52
.set_item(self.storage_key(filename).as_str(), &toml_str)
53
.unwrap();
54
}
55
});
56
});
57
}
58
59
/// Deserialize a [`toml::Table`]. If the file does not exist, `None` will
60
/// be returned.
61
///
62
/// # Arguments
63
/// * `filename` - The name of the preferences file, without the file extension.
64
pub(crate) fn load(&self, filename: &str) -> Option<toml::Table> {
65
if let Ok(Some(storage)) = window().unwrap().local_storage() {
66
let storage_key = self.storage_key(filename);
67
let Ok(Some(toml_str)) = storage.get_item(&storage_key) else {
68
return None;
69
};
70
71
let table_value = match toml::from_str::<toml::Value>(&toml_str) {
72
Ok(table_value) => table_value,
73
Err(e) => {
74
error!("Error parsing preferences file: {}", e);
75
return None;
76
}
77
};
78
79
match table_value {
80
toml::Value::Table(table) => Some(table),
81
_ => {
82
error!("Preferences file must be a table");
83
None
84
}
85
}
86
} else {
87
None
88
}
89
}
90
}
91
92