asset: AssetServer versioning and load group status
This commit is contained in:
		
							parent
							
								
									9d80b5965e
								
							
						
					
					
						commit
						9a51b3e0fd
					
				@ -20,4 +20,5 @@ serde = { version = "1", features = ["derive"] }
 | 
				
			|||||||
crossbeam-channel = "0.4.2"
 | 
					crossbeam-channel = "0.4.2"
 | 
				
			||||||
anyhow = "1.0"
 | 
					anyhow = "1.0"
 | 
				
			||||||
thiserror = "1.0"
 | 
					thiserror = "1.0"
 | 
				
			||||||
 | 
					log = { version = "0.4", features = ["release_max_level_info"] }
 | 
				
			||||||
notify = { version = "5.0.0-pre.2", optional = true }
 | 
					notify = { version = "5.0.0-pre.2", optional = true }
 | 
				
			||||||
@ -14,6 +14,7 @@ use std::{
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
use thiserror::Error;
 | 
					use thiserror::Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type AssetVersion = usize;
 | 
				
			||||||
#[derive(Error, Debug)]
 | 
					#[derive(Error, Debug)]
 | 
				
			||||||
pub enum AssetServerError {
 | 
					pub enum AssetServerError {
 | 
				
			||||||
    #[error("Asset folder path is not a directory.")]
 | 
					    #[error("Asset folder path is not a directory.")]
 | 
				
			||||||
@ -38,8 +39,32 @@ struct LoaderThread {
 | 
				
			|||||||
    requests: Arc<RwLock<Vec<LoadRequest>>>,
 | 
					    requests: Arc<RwLock<Vec<LoadRequest>>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
 | 
					pub struct AssetInfo {
 | 
				
			||||||
 | 
					    handle_id: HandleId,
 | 
				
			||||||
 | 
					    path: PathBuf,
 | 
				
			||||||
 | 
					    load_state: LoadState,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Eq, PartialEq)]
 | 
				
			||||||
 | 
					pub enum LoadState {
 | 
				
			||||||
 | 
					    Loading(AssetVersion),
 | 
				
			||||||
 | 
					    Loaded(AssetVersion),
 | 
				
			||||||
 | 
					    Failed(AssetVersion),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl LoadState {
 | 
				
			||||||
 | 
					    pub fn get_version(&self) -> AssetVersion {
 | 
				
			||||||
 | 
					        match *self {
 | 
				
			||||||
 | 
					            LoadState::Loaded(version) => version,
 | 
				
			||||||
 | 
					            LoadState::Loading(version) => version,
 | 
				
			||||||
 | 
					            LoadState::Failed(version) => version,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct AssetServer {
 | 
					pub struct AssetServer {
 | 
				
			||||||
    asset_folders: Vec<PathBuf>,
 | 
					    asset_folders: RwLock<Vec<PathBuf>>,
 | 
				
			||||||
    loader_threads: RwLock<Vec<LoaderThread>>,
 | 
					    loader_threads: RwLock<Vec<LoaderThread>>,
 | 
				
			||||||
    max_loader_threads: usize,
 | 
					    max_loader_threads: usize,
 | 
				
			||||||
    asset_handlers: Arc<RwLock<Vec<Box<dyn AssetLoadRequestHandler>>>>,
 | 
					    asset_handlers: Arc<RwLock<Vec<Box<dyn AssetLoadRequestHandler>>>>,
 | 
				
			||||||
@ -47,7 +72,8 @@ pub struct AssetServer {
 | 
				
			|||||||
    loaders: Vec<Resources>,
 | 
					    loaders: Vec<Resources>,
 | 
				
			||||||
    extension_to_handler_index: HashMap<String, usize>,
 | 
					    extension_to_handler_index: HashMap<String, usize>,
 | 
				
			||||||
    extension_to_loader_index: HashMap<String, usize>,
 | 
					    extension_to_loader_index: HashMap<String, usize>,
 | 
				
			||||||
    path_to_handle: RwLock<HashMap<PathBuf, HandleId>>,
 | 
					    asset_info: RwLock<HashMap<HandleId, AssetInfo>>,
 | 
				
			||||||
 | 
					    asset_info_paths: RwLock<HashMap<PathBuf, HandleId>>,
 | 
				
			||||||
    #[cfg(feature = "filesystem_watcher")]
 | 
					    #[cfg(feature = "filesystem_watcher")]
 | 
				
			||||||
    filesystem_watcher: Arc<RwLock<Option<FilesystemWatcher>>>,
 | 
					    filesystem_watcher: Arc<RwLock<Option<FilesystemWatcher>>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -55,16 +81,17 @@ pub struct AssetServer {
 | 
				
			|||||||
impl Default for AssetServer {
 | 
					impl Default for AssetServer {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        AssetServer {
 | 
					        AssetServer {
 | 
				
			||||||
            max_loader_threads: 4,
 | 
					 | 
				
			||||||
            asset_folders: Vec::new(),
 | 
					 | 
				
			||||||
            loader_threads: RwLock::new(Vec::new()),
 | 
					 | 
				
			||||||
            asset_handlers: Arc::new(RwLock::new(Vec::new())),
 | 
					 | 
				
			||||||
            loaders: Vec::new(),
 | 
					 | 
				
			||||||
            extension_to_handler_index: HashMap::new(),
 | 
					 | 
				
			||||||
            extension_to_loader_index: HashMap::new(),
 | 
					 | 
				
			||||||
            path_to_handle: RwLock::new(HashMap::default()),
 | 
					 | 
				
			||||||
            #[cfg(feature = "filesystem_watcher")]
 | 
					            #[cfg(feature = "filesystem_watcher")]
 | 
				
			||||||
            filesystem_watcher: Arc::new(RwLock::new(None)),
 | 
					            filesystem_watcher: Arc::new(RwLock::new(None)),
 | 
				
			||||||
 | 
					            max_loader_threads: 4,
 | 
				
			||||||
 | 
					            asset_folders: Default::default(),
 | 
				
			||||||
 | 
					            loader_threads: Default::default(),
 | 
				
			||||||
 | 
					            asset_handlers: Default::default(),
 | 
				
			||||||
 | 
					            loaders: Default::default(),
 | 
				
			||||||
 | 
					            extension_to_handler_index: Default::default(),
 | 
				
			||||||
 | 
					            extension_to_loader_index: Default::default(),
 | 
				
			||||||
 | 
					            asset_info_paths: Default::default(),
 | 
				
			||||||
 | 
					            asset_info: Default::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -100,20 +127,20 @@ impl AssetServer {
 | 
				
			|||||||
        self.loaders.push(resources);
 | 
					        self.loaders.push(resources);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn load_asset_folder<P: AsRef<Path>>(&mut self, path: P) -> Result<(), AssetServerError> {
 | 
					    pub fn load_asset_folder<P: AsRef<Path>>(&self, path: P) -> Result<Vec<HandleId>, AssetServerError> {
 | 
				
			||||||
        let root_path = self.get_root_path()?;
 | 
					        let root_path = self.get_root_path()?;
 | 
				
			||||||
        let asset_folder = root_path.join(path);
 | 
					        let asset_folder = root_path.join(path);
 | 
				
			||||||
        self.load_assets_in_folder_recursive(&asset_folder)?;
 | 
					        let handle_ids = self.load_assets_in_folder_recursive(&asset_folder)?;
 | 
				
			||||||
        self.asset_folders.push(asset_folder);
 | 
					        self.asset_folders.write().unwrap().push(asset_folder);
 | 
				
			||||||
        Ok(())
 | 
					        Ok(handle_ids)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_handle<T, P: AsRef<Path>>(&self, path: P) -> Option<Handle<T>> {
 | 
					    pub fn get_handle<T, P: AsRef<Path>>(&self, path: P) -> Option<Handle<T>> {
 | 
				
			||||||
        self.path_to_handle
 | 
					        self.asset_info_paths
 | 
				
			||||||
            .read()
 | 
					            .read()
 | 
				
			||||||
            .unwrap()
 | 
					            .unwrap()
 | 
				
			||||||
            .get(path.as_ref())
 | 
					            .get(path.as_ref())
 | 
				
			||||||
            .map(|h| Handle::from(*h))
 | 
					            .map(|handle_id| Handle::from(*handle_id))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(feature = "filesystem_watcher")]
 | 
					    #[cfg(feature = "filesystem_watcher")]
 | 
				
			||||||
@ -138,8 +165,8 @@ impl AssetServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let _ = filesystem_watcher.get_or_insert_with(|| FilesystemWatcher::default());
 | 
					        let _ = filesystem_watcher.get_or_insert_with(|| FilesystemWatcher::default());
 | 
				
			||||||
        // watch current files
 | 
					        // watch current files
 | 
				
			||||||
        let path_to_handle = self.path_to_handle.read().unwrap();
 | 
					        let asset_info_paths = self.asset_info_paths.read().unwrap();
 | 
				
			||||||
        for asset_path in path_to_handle.keys() {
 | 
					        for asset_path in asset_info_paths.keys() {
 | 
				
			||||||
            Self::watch_path_for_changes(&mut filesystem_watcher, asset_path)?;
 | 
					            Self::watch_path_for_changes(&mut filesystem_watcher, asset_path)?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,7 +260,6 @@ impl AssetServer {
 | 
				
			|||||||
                let asset = loader.load_from_file(path)?;
 | 
					                let asset = loader.load_from_file(path)?;
 | 
				
			||||||
                let handle = Handle::from(handle_id);
 | 
					                let handle = Handle::from(handle_id);
 | 
				
			||||||
                assets.set(handle, asset);
 | 
					                assets.set(handle, asset);
 | 
				
			||||||
                assets.set_path(handle, path);
 | 
					 | 
				
			||||||
                Ok(handle)
 | 
					                Ok(handle)
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Err(AssetServerError::MissingAssetHandler)
 | 
					                Err(AssetServerError::MissingAssetHandler)
 | 
				
			||||||
@ -251,13 +277,27 @@ impl AssetServer {
 | 
				
			|||||||
                    .to_str()
 | 
					                    .to_str()
 | 
				
			||||||
                    .expect("Extension should be a valid string."),
 | 
					                    .expect("Extension should be a valid string."),
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
 | 
					                let mut new_version = 0;
 | 
				
			||||||
                let handle_id = {
 | 
					                let handle_id = {
 | 
				
			||||||
                    let mut path_to_handle = self.path_to_handle.write().unwrap();
 | 
					                    let mut asset_info = self.asset_info.write().unwrap();
 | 
				
			||||||
                    if let Some(handle_id) = path_to_handle.get(path) {
 | 
					                    let mut asset_info_paths = self.asset_info_paths.write().unwrap();
 | 
				
			||||||
                        *handle_id
 | 
					                    if let Some(asset_info) = asset_info_paths
 | 
				
			||||||
 | 
					                        .get(path)
 | 
				
			||||||
 | 
					                        .and_then(|handle_id| asset_info.get_mut(&handle_id))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        asset_info.load_state = if let LoadState::Loaded(_version) = asset_info.load_state { new_version += 1; LoadState::Loading(new_version) } else { LoadState::Loading(new_version) };
 | 
				
			||||||
 | 
					                        asset_info.handle_id
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        let handle_id = HandleId::new();
 | 
					                        let handle_id = HandleId::new();
 | 
				
			||||||
                        path_to_handle.insert(path.to_owned(), handle_id.clone());
 | 
					                        asset_info.insert(
 | 
				
			||||||
 | 
					                            handle_id,
 | 
				
			||||||
 | 
					                            AssetInfo {
 | 
				
			||||||
 | 
					                                handle_id,
 | 
				
			||||||
 | 
					                                path: path.to_owned(),
 | 
				
			||||||
 | 
					                                load_state: LoadState::Loading(new_version),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                        asset_info_paths.insert(path.to_owned(), handle_id);
 | 
				
			||||||
                        handle_id
 | 
					                        handle_id
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
@ -266,6 +306,7 @@ impl AssetServer {
 | 
				
			|||||||
                    handle_id,
 | 
					                    handle_id,
 | 
				
			||||||
                    path: path.to_owned(),
 | 
					                    path: path.to_owned(),
 | 
				
			||||||
                    handler_index: *index,
 | 
					                    handler_index: *index,
 | 
				
			||||||
 | 
					                    version: new_version,
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // TODO: watching each asset explicitly is a simpler implementation, its possible it would be more efficient to watch
 | 
					                // TODO: watching each asset explicitly is a simpler implementation, its possible it would be more efficient to watch
 | 
				
			||||||
@ -281,7 +322,42 @@ impl AssetServer {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_load_state(&self, handle_id: HandleId, load_state: LoadState) {
 | 
				
			||||||
 | 
					        self.asset_info
 | 
				
			||||||
 | 
					            .write()
 | 
				
			||||||
 | 
					            .unwrap()
 | 
				
			||||||
 | 
					            .get_mut(&handle_id)
 | 
				
			||||||
 | 
					            .map(|asset_info| {
 | 
				
			||||||
 | 
					                if load_state.get_version() >= asset_info.load_state.get_version() {
 | 
				
			||||||
 | 
					                    asset_info.load_state = load_state;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pub fn get_load_state_untyped(&self, handle_id: HandleId) -> Option<LoadState> {
 | 
				
			||||||
 | 
					        self.asset_info.read().unwrap().get(&handle_id).map(|asset_info| asset_info.load_state.clone())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_load_state<T>(&self, handle: Handle<T>) -> Option<LoadState> {
 | 
				
			||||||
 | 
					        self.get_load_state_untyped(handle.id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_group_load_state(&self, handle_ids: &[HandleId]) -> Option<LoadState> {
 | 
				
			||||||
 | 
					        let mut load_state = LoadState::Loaded(0);
 | 
				
			||||||
 | 
					        for handle_id in handle_ids.iter() {
 | 
				
			||||||
 | 
					            match self.get_load_state_untyped(*handle_id) {
 | 
				
			||||||
 | 
					                Some(LoadState::Loaded(_)) => continue,
 | 
				
			||||||
 | 
					                Some(LoadState::Loading(_)) => {load_state = LoadState::Loading(0);},
 | 
				
			||||||
 | 
					                Some(LoadState::Failed(_)) => return Some(LoadState::Failed(0)),
 | 
				
			||||||
 | 
					                None => return None,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Some(load_state)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn send_request_to_loader_thread(&self, load_request: LoadRequest) {
 | 
					    fn send_request_to_loader_thread(&self, load_request: LoadRequest) {
 | 
				
			||||||
 | 
					        // NOTE: This lock makes the call to Arc::strong_count safe. Removing (or reordering) it could result in undefined behavior
 | 
				
			||||||
        let mut loader_threads = self.loader_threads.write().unwrap();
 | 
					        let mut loader_threads = self.loader_threads.write().unwrap();
 | 
				
			||||||
        if loader_threads.len() < self.max_loader_threads {
 | 
					        if loader_threads.len() < self.max_loader_threads {
 | 
				
			||||||
            let loader_thread = LoaderThread {
 | 
					            let loader_thread = LoaderThread {
 | 
				
			||||||
@ -330,7 +406,7 @@ impl AssetServer {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn load_assets_in_folder_recursive(&self, path: &Path) -> Result<(), AssetServerError> {
 | 
					    fn load_assets_in_folder_recursive(&self, path: &Path) -> Result<Vec<HandleId>, AssetServerError> {
 | 
				
			||||||
        if !path.is_dir() {
 | 
					        if !path.is_dir() {
 | 
				
			||||||
            return Err(AssetServerError::AssetFolderNotADirectory(
 | 
					            return Err(AssetServerError::AssetFolderNotADirectory(
 | 
				
			||||||
                path.to_str().unwrap().to_string(),
 | 
					                path.to_str().unwrap().to_string(),
 | 
				
			||||||
@ -338,21 +414,24 @@ impl AssetServer {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let root_path = self.get_root_path()?;
 | 
					        let root_path = self.get_root_path()?;
 | 
				
			||||||
 | 
					        let mut handle_ids = Vec::new();
 | 
				
			||||||
        for entry in fs::read_dir(path)? {
 | 
					        for entry in fs::read_dir(path)? {
 | 
				
			||||||
            let entry = entry?;
 | 
					            let entry = entry?;
 | 
				
			||||||
            let child_path = entry.path();
 | 
					            let child_path = entry.path();
 | 
				
			||||||
            if !child_path.is_dir() {
 | 
					            if !child_path.is_dir() {
 | 
				
			||||||
                let relative_child_path = child_path.strip_prefix(&root_path).unwrap();
 | 
					                let relative_child_path = child_path.strip_prefix(&root_path).unwrap();
 | 
				
			||||||
                let _ = self.load_untyped(
 | 
					                let handle = self.load_untyped(
 | 
				
			||||||
                    relative_child_path
 | 
					                    relative_child_path
 | 
				
			||||||
                        .to_str()
 | 
					                        .to_str()
 | 
				
			||||||
                        .expect("Path should be a valid string"),
 | 
					                        .expect("Path should be a valid string"),
 | 
				
			||||||
                );
 | 
					                )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                handle_ids.push(handle);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                self.load_assets_in_folder_recursive(&child_path)?;
 | 
					                handle_ids.extend(self.load_assets_in_folder_recursive(&child_path)?);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(handle_ids)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,10 +6,7 @@ use bevy_app::{AppBuilder, Events, FromResources};
 | 
				
			|||||||
use bevy_core::bytes::Bytes;
 | 
					use bevy_core::bytes::Bytes;
 | 
				
			||||||
use bevy_type_registry::RegisterType;
 | 
					use bevy_type_registry::RegisterType;
 | 
				
			||||||
use legion::prelude::*;
 | 
					use legion::prelude::*;
 | 
				
			||||||
use std::{
 | 
					use std::collections::HashMap;
 | 
				
			||||||
    collections::HashMap,
 | 
					 | 
				
			||||||
    path::{Path, PathBuf},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum AssetEvent<T: 'static> {
 | 
					pub enum AssetEvent<T: 'static> {
 | 
				
			||||||
    Created { handle: Handle<T> },
 | 
					    Created { handle: Handle<T> },
 | 
				
			||||||
@ -19,7 +16,6 @@ pub enum AssetEvent<T: 'static> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct Assets<T: 'static> {
 | 
					pub struct Assets<T: 'static> {
 | 
				
			||||||
    assets: HashMap<Handle<T>, T>,
 | 
					    assets: HashMap<Handle<T>, T>,
 | 
				
			||||||
    paths: HashMap<PathBuf, Handle<T>>,
 | 
					 | 
				
			||||||
    events: Events<AssetEvent<T>>,
 | 
					    events: Events<AssetEvent<T>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,17 +23,12 @@ impl<T> Default for Assets<T> {
 | 
				
			|||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Assets {
 | 
					        Assets {
 | 
				
			||||||
            assets: HashMap::default(),
 | 
					            assets: HashMap::default(),
 | 
				
			||||||
            paths: HashMap::default(),
 | 
					 | 
				
			||||||
            events: Events::default(),
 | 
					            events: Events::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> Assets<T> {
 | 
					impl<T> Assets<T> {
 | 
				
			||||||
    pub fn get_with_path<P: AsRef<Path>>(&mut self, path: P) -> Option<Handle<T>> {
 | 
					 | 
				
			||||||
        self.paths.get(path.as_ref()).map(|handle| *handle)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn add(&mut self, asset: T) -> Handle<T> {
 | 
					    pub fn add(&mut self, asset: T) -> Handle<T> {
 | 
				
			||||||
        let handle = Handle::new();
 | 
					        let handle = Handle::new();
 | 
				
			||||||
        self.assets.insert(handle, asset);
 | 
					        self.assets.insert(handle, asset);
 | 
				
			||||||
@ -68,11 +59,7 @@ impl<T> Assets<T> {
 | 
				
			|||||||
        handle
 | 
					        handle
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn set_path<P: AsRef<Path>>(&mut self, handle: Handle<T>, path: P) {
 | 
					    pub fn get_with_id(&self, id: HandleId) -> Option<&T> {
 | 
				
			||||||
        self.paths.insert(path.as_ref().to_owned(), handle);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub fn get_id(&self, id: HandleId) -> Option<&T> {
 | 
					 | 
				
			||||||
        self.assets.get(&Handle::from_id(id))
 | 
					        self.assets.get(&Handle::from_id(id))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
use crate::{AssetLoadError, AssetLoader, AssetResult, Handle, HandleId};
 | 
					use crate::{AssetLoadError, AssetLoader, AssetResult, AssetVersion, Handle, HandleId};
 | 
				
			||||||
use anyhow::Result;
 | 
					use anyhow::Result;
 | 
				
			||||||
use crossbeam_channel::Sender;
 | 
					use crossbeam_channel::Sender;
 | 
				
			||||||
use fs::File;
 | 
					use fs::File;
 | 
				
			||||||
@ -10,6 +10,7 @@ pub struct LoadRequest {
 | 
				
			|||||||
    pub path: PathBuf,
 | 
					    pub path: PathBuf,
 | 
				
			||||||
    pub handle_id: HandleId,
 | 
					    pub handle_id: HandleId,
 | 
				
			||||||
    pub handler_index: usize,
 | 
					    pub handler_index: usize,
 | 
				
			||||||
 | 
					    pub version: AssetVersion,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait AssetLoadRequestHandler: Send + Sync + 'static {
 | 
					pub trait AssetLoadRequestHandler: Send + Sync + 'static {
 | 
				
			||||||
@ -54,6 +55,7 @@ where
 | 
				
			|||||||
            handle: Handle::from(load_request.handle_id),
 | 
					            handle: Handle::from(load_request.handle_id),
 | 
				
			||||||
            result,
 | 
					            result,
 | 
				
			||||||
            path: load_request.path.clone(),
 | 
					            path: load_request.path.clone(),
 | 
				
			||||||
 | 
					            version: load_request.version,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.sender
 | 
					        self.sender
 | 
				
			||||||
            .send(asset_result)
 | 
					            .send(asset_result)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
use crate::{Assets, Handle};
 | 
					use crate::{AssetServer, Assets, Handle, AssetVersion, LoadState};
 | 
				
			||||||
use anyhow::Result;
 | 
					use anyhow::Result;
 | 
				
			||||||
use crossbeam_channel::{Receiver, Sender, TryRecvError};
 | 
					use crossbeam_channel::{Receiver, Sender, TryRecvError};
 | 
				
			||||||
use fs::File;
 | 
					use fs::File;
 | 
				
			||||||
@ -34,6 +34,7 @@ pub struct AssetResult<T: 'static> {
 | 
				
			|||||||
    pub result: Result<T, AssetLoadError>,
 | 
					    pub result: Result<T, AssetLoadError>,
 | 
				
			||||||
    pub handle: Handle<T>,
 | 
					    pub handle: Handle<T>,
 | 
				
			||||||
    pub path: PathBuf,
 | 
					    pub path: PathBuf,
 | 
				
			||||||
 | 
					    pub version: AssetVersion,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct AssetChannel<T: 'static> {
 | 
					pub struct AssetChannel<T: 'static> {
 | 
				
			||||||
@ -50,14 +51,22 @@ impl<T> AssetChannel<T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub fn update_asset_storage_system<T>(
 | 
					pub fn update_asset_storage_system<T>(
 | 
				
			||||||
    asset_channel: Res<AssetChannel<T>>,
 | 
					    asset_channel: Res<AssetChannel<T>>,
 | 
				
			||||||
 | 
					    asset_server: Res<AssetServer>,
 | 
				
			||||||
    mut assets: ResMut<Assets<T>>,
 | 
					    mut assets: ResMut<Assets<T>>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        match asset_channel.receiver.try_recv() {
 | 
					        match asset_channel.receiver.try_recv() {
 | 
				
			||||||
            Ok(result) => {
 | 
					            Ok(result) => {
 | 
				
			||||||
                let asset = result.result.unwrap();
 | 
					                match result.result {
 | 
				
			||||||
 | 
					                    Ok(asset) => {
 | 
				
			||||||
                        assets.set(result.handle, asset);
 | 
					                        assets.set(result.handle, asset);
 | 
				
			||||||
                assets.set_path(result.handle, &result.path);
 | 
					                        asset_server.set_load_state(result.handle.id, LoadState::Loaded(result.version));
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    Err(err) => {
 | 
				
			||||||
 | 
					                        asset_server.set_load_state(result.handle.id, LoadState::Failed(result.version));
 | 
				
			||||||
 | 
					                        log::error!("Failed to load asset: {:?}", err);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Err(TryRecvError::Empty) => {
 | 
					            Err(TryRecvError::Empty) => {
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
				
			|||||||
@ -27,11 +27,11 @@ impl FromResources for SceneLoader {
 | 
				
			|||||||
impl AssetLoader<Scene> for SceneLoader {
 | 
					impl AssetLoader<Scene> for SceneLoader {
 | 
				
			||||||
    fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<Scene> {
 | 
					    fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<Scene> {
 | 
				
			||||||
        let registry = self.property_type_registry.read().unwrap();
 | 
					        let registry = self.property_type_registry.read().unwrap();
 | 
				
			||||||
        let mut deserializer = ron::de::Deserializer::from_bytes(&bytes).unwrap();
 | 
					        let mut deserializer = ron::de::Deserializer::from_bytes(&bytes)?;
 | 
				
			||||||
        let scene_deserializer = SceneDeserializer {
 | 
					        let scene_deserializer = SceneDeserializer {
 | 
				
			||||||
            property_type_registry: ®istry,
 | 
					            property_type_registry: ®istry,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
 | 
					        let scene = scene_deserializer.deserialize(&mut deserializer)?;
 | 
				
			||||||
        Ok(scene)
 | 
					        Ok(scene)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn extensions(&self) -> &[&str] {
 | 
					    fn extensions(&self) -> &[&str] {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user