goud_engine/assets/server/
async_operations.rs1#[cfg(all(feature = "native", not(feature = "web")))]
7use super::core::AssetServer;
8#[cfg(all(feature = "native", not(feature = "web")))]
9use super::core::LoadResult;
10#[cfg(all(feature = "native", not(feature = "web")))]
11use crate::assets::{Asset, AssetHandle, AssetId, AssetLoadError, AssetPath, LoadContext};
12#[cfg(all(feature = "native", not(feature = "web")))]
13use std::path::Path;
14
15#[cfg(all(feature = "native", not(feature = "web")))]
16impl AssetServer {
17 pub fn load_async<A: Asset>(&mut self, path: impl AsRef<Path>) -> AssetHandle<A> {
44 let asset_path = AssetPath::new(path.as_ref().to_str().unwrap_or_default());
45
46 if let Some(handle) = self.storage.get_handle_by_path::<A>(asset_path.as_str()) {
48 return handle;
49 }
50
51 let handle = self.storage.reserve_with_path::<A>(asset_path.clone());
53 if let Some(entry) = self.storage.get_entry_mut::<A>(&handle) {
54 entry.set_progress(0.0);
55 }
56
57 let extension = match asset_path.extension() {
59 Some(ext) => ext.to_string(),
60 None => {
61 if let Some(entry) = self.storage.get_entry_mut::<A>(&handle) {
62 entry.set_failed("No file extension");
63 }
64 return handle;
65 }
66 };
67 let loader = match self.loaders.get(&extension) {
68 Some(l) => l.clone_boxed(),
69 None => {
70 if let Some(entry) = self.storage.get_entry_mut::<A>(&handle) {
71 entry.set_failed(format!("No loader for extension: {}", extension));
72 }
73 return handle;
74 }
75 };
76
77 let asset_root = self.asset_root.clone();
79 let sender = self.load_sender.clone();
80 let handle_index = handle.index();
81 let handle_generation = handle.generation();
82 let asset_id = AssetId::of::<A>();
83 let path_str = asset_path.as_str().to_string();
84
85 rayon::spawn(move || {
86 let full_path = asset_root.join(&path_str);
87 let result = std::fs::read(&full_path)
88 .map_err(|e| AssetLoadError::io_error(&full_path, e))
89 .and_then(|bytes| {
90 let owned_path = AssetPath::from_string(path_str);
91 let mut context = LoadContext::new(owned_path);
92 loader.load_erased(&bytes, &mut context)
93 });
94 let _ = sender.send(LoadResult {
95 handle_index,
96 handle_generation,
97 asset_id,
98 result,
99 });
100 });
101
102 handle
103 }
104}
105
106#[cfg(feature = "native")]
107impl super::core::AssetServer {
108 pub fn process_loads(&mut self) -> usize {
117 let mut count = 0;
118 while let Ok(load_result) = self.load_receiver.try_recv() {
119 match load_result.result {
120 Ok(boxed) => {
121 self.storage.set_loaded_raw(
122 load_result.asset_id,
123 load_result.handle_index,
124 load_result.handle_generation,
125 boxed,
126 );
127 }
128 Err(error) => {
129 self.storage.set_failed_raw(
130 load_result.asset_id,
131 load_result.handle_index,
132 load_result.handle_generation,
133 error.to_string(),
134 );
135 }
136 }
137 count += 1;
138 }
139 count
140 }
141}