notan_app/assets/
manager.rs1use super::asset::Asset;
2use super::list::AssetList;
3use super::loader::*;
4use super::storage::AssetStorage;
5use super::utils::DoneSignal;
6
7use hashbrown::HashMap;
8use std::any::TypeId;
9use std::path::Path;
10use std::rc::Rc;
11
12#[cfg(feature = "drop_files")]
13use crate::DroppedFile;
14
15pub struct Assets {
16 storage: AssetStorage,
17 pub(crate) loaders: HashMap<String, LoaderCallback>,
18 byte_loader: LoaderCallback,
19}
20
21impl Assets {
22 pub(crate) fn new() -> Self {
23 let bytes_id = TypeId::of::<Vec<u8>>();
24 let byte_loader = LoaderCallback::Basic(
25 Some(bytes_id),
26 Rc::new(|storage, id, bytes| storage.parse::<Vec<u8>>(id, bytes)),
27 );
28
29 Self {
30 loaders: HashMap::new(),
31 storage: AssetStorage::default(),
32 byte_loader,
33 }
34 }
35
36 pub(crate) fn tick<S>(&mut self, mut params: LoaderParams<S>) -> Result<(), String> {
37 if let Some(mut to_update) = self.storage.try_load() {
38 while let Some((id, data)) = to_update.pop() {
39 let ext = Path::new(&id)
40 .extension()
41 .map(|ext| ext.to_str().unwrap())
42 .unwrap_or("");
43
44 let loader = match self.loaders.get(ext) {
45 Some(loader) => loader,
46 None => {
47 log::warn!("Not found a loader for '{id}', loading as bytes (Vec<u8>)");
48 &self.byte_loader
49 }
50 };
51
52 loader.exec(&id, data, &mut self.storage, &mut params)?;
53 self.storage.clean_asset(&id)?;
54 }
55
56 self.storage.clean_ready_assets();
57 }
58
59 Ok(())
60 }
61
62 pub fn add_loader(&mut self, loader: AssetLoader) {
63 if let Err(e) = loader.apply(self) {
64 log::error!("{e}");
65 }
66 }
67
68 fn load(&mut self, id: &str) -> Result<DoneSignal, String> {
69 let ext = Path::new(id)
70 .extension()
71 .map(|ext| ext.to_str().unwrap())
72 .unwrap_or("");
73
74 let loader = match self.loaders.get(ext) {
75 Some(loader) => loader,
76 None => {
77 log::warn!("Not found a loader for '{id}', loading as bytes (Vec<u8>)");
78 &self.byte_loader
79 }
80 };
81
82 Ok(match loader.type_id() {
83 Some(type_id) => self.storage.register(id, type_id),
84 None => return Err("Loader without output type id".to_string()),
85 })
86 }
87
88 #[cfg(all(target_arch = "wasm32", feature = "drop_files"))]
89 fn load_wasm_dropped_file(&mut self, file: &DroppedFile) -> Result<DoneSignal, String> {
90 let id = file.name.clone();
91 let ext = Path::new(&id)
92 .extension()
93 .map(|ext| ext.to_str().unwrap())
94 .unwrap_or("");
95
96 let loader = match self.loaders.get(ext) {
97 Some(loader) => loader,
98 None => {
99 log::warn!(
100 "Not found a loader for '{}', loading as bytes (Vec<u8>)",
101 id
102 );
103 &self.byte_loader
104 }
105 };
106
107 Ok(match loader.type_id() {
108 Some(type_id) => self
109 .storage
110 .register_wasm_dropped_file(&id, file, type_id)?,
111 None => return Err("Loader without output type id".to_string()),
112 })
113 }
114
115 pub fn load_asset<A>(&mut self, id: &str) -> Result<Asset<A>, String>
116 where
117 A: Send + Sync + 'static,
118 {
119 let _ = self.load(id)?;
120 self.storage.get(id, true)
121 }
122
123 #[cfg(all(target_arch = "wasm32", feature = "drop_files"))]
124 fn load_wasm_dropped_file_asset<A>(&mut self, file: &DroppedFile) -> Result<Asset<A>, String>
125 where
126 A: Send + Sync + 'static,
127 {
128 let _ = self.load_wasm_dropped_file(file)?;
129 self.storage.get(&file.name, true)
130 }
131
132 pub fn load_list(&mut self, paths: &[&str]) -> Result<AssetList, String> {
133 let mut list = AssetList::new(self.storage.tracker.clone());
134 for id in paths {
135 let loaded = self.load(id)?;
136 list.insert(id, loaded);
137 }
138 Ok(list)
139 }
140
141 #[cfg(feature = "drop_files")]
142 pub fn load_dropped_file<A>(&mut self, file: &DroppedFile) -> Result<Asset<A>, String>
143 where
144 A: Send + Sync + 'static,
145 {
146 if let Some(path) = &file.path {
147 if let Some(id) = path.to_str() {
148 return self.load_asset(id);
149 }
150 }
151
152 #[cfg(target_arch = "wasm32")]
153 {
154 self.load_wasm_dropped_file_asset(file)
155 }
156
157 #[cfg(not(target_arch = "wasm32"))]
158 Err(format!("Can't load the dropped file {}", file.name))
159 }
160}