resource: fix wait_for_load haning when using handles from 'request_raw'
This commit is contained in:
parent
15807a3dc1
commit
1b08482ef7
|
@ -7,7 +7,7 @@ use notify_debouncer_full::{DebouncedEvent, FileIdMap};
|
|||
use thiserror::Error;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{gltf::ModelLoader, loader::{ImageLoader, LoaderError, ResourceLoader}, resource::ResHandle, ResourceData, ResourceState};
|
||||
use crate::{gltf::ModelLoader, loader::{ImageLoader, LoaderError, ResourceLoader}, resource::ResHandle, ResourceData, ResourceState, UntypedResHandle};
|
||||
|
||||
/// A trait for type erased storage of a resource.
|
||||
/// Implemented for [`ResHandle<T>`]
|
||||
|
@ -26,6 +26,7 @@ pub trait ResourceStorage: Send + Sync + Any + 'static {
|
|||
fn is_watched(&self) -> bool;
|
||||
fn is_loaded(&self) -> bool;
|
||||
fn set_state(&self, new: ResourceState);
|
||||
fn clone_untyped(&self) -> UntypedResHandle;
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -121,54 +122,14 @@ impl ResourceManager {
|
|||
///
|
||||
/// Loading resources is done asynchronously on a task spawned by `async-std`. You can use the
|
||||
/// handle to check if the resource is loaded.
|
||||
#[inline(always)]
|
||||
pub fn request<T>(&self, path: &str) -> Result<ResHandle<T>, RequestError>
|
||||
where
|
||||
T: ResourceData
|
||||
{
|
||||
let mut state = self.state_mut();
|
||||
match state.resources.get(&path.to_string()) {
|
||||
Some(res) => {
|
||||
let res = res.clone().as_arc_any();
|
||||
let res: Arc<ResHandle<T>> = res.downcast::<ResHandle<T>>().expect("Failure to downcast resource");
|
||||
let res = ResHandle::<T>::clone(&res);
|
||||
|
||||
Ok(res)
|
||||
},
|
||||
None => {
|
||||
if let Some(loader) = state.loaders.iter()
|
||||
.find(|l| l.does_support_file(path)) {
|
||||
|
||||
// Load the resource and store it
|
||||
let loader = Arc::clone(loader); // stop borrowing from self
|
||||
let res = loader.load(self.clone(), path);
|
||||
|
||||
let handle = ResHandle::<T>::new_loading(Some(path));
|
||||
|
||||
let thand = handle.clone();
|
||||
task::spawn(async move {
|
||||
match res.await {
|
||||
Ok(data) => {
|
||||
let mut d = thand.write();
|
||||
d.state = ResourceState::Ready(data);
|
||||
d.condvar.1.notify_all();
|
||||
}
|
||||
Err(err) => {
|
||||
let mut d = thand.write();
|
||||
d.state = ResourceState::Error(Arc::new(err));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let res: Arc<dyn ResourceStorage> = Arc::from(handle.clone());
|
||||
state.resources.insert(path.to_string(), res.clone());
|
||||
state.uuid_resources.insert(res.uuid(), res);
|
||||
|
||||
Ok(handle)
|
||||
} else {
|
||||
Err(RequestError::UnsupportedFileExtension(path.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
self.request_raw(path)
|
||||
.map(|res| res.as_typed::<T>()
|
||||
.expect("mismatched asset type, cannot downcast"))
|
||||
}
|
||||
|
||||
/// Request a resource without downcasting to a `ResHandle<T>`.
|
||||
|
@ -177,11 +138,11 @@ impl ResourceManager {
|
|||
/// let arc_any = res_arc.as_arc_any();
|
||||
/// let res: Arc<ResHandle<T>> = res.downcast::<ResHandle<T>>().expect("Failure to downcast resource");
|
||||
/// ```
|
||||
pub fn request_raw(&self, path: &str) -> Result<Arc<dyn ResourceStorage>, RequestError> {
|
||||
pub fn request_raw(&self, path: &str) -> Result<UntypedResHandle, RequestError> {
|
||||
let mut state = self.state_mut();
|
||||
match state.resources.get(&path.to_string()) {
|
||||
Some(res) => {
|
||||
Ok(res.clone())
|
||||
Ok(res.clone().clone_untyped())
|
||||
},
|
||||
None => {
|
||||
if let Some(loader) = state.loaders.iter()
|
||||
|
@ -192,24 +153,29 @@ impl ResourceManager {
|
|||
let res = loader.load(self.clone(), path);
|
||||
|
||||
let handle = loader.create_erased_handle();
|
||||
//let handle = ResHandle::<T>::new_loading();
|
||||
|
||||
let thand = handle.clone();
|
||||
let untyped = handle.clone_untyped();
|
||||
untyped.write().path = Some(path.to_string());
|
||||
|
||||
task::spawn(async move {
|
||||
match res.await {
|
||||
Ok(data) => {
|
||||
thand.set_state(ResourceState::Ready(data));
|
||||
let mut d = untyped.write();
|
||||
d.state = ResourceState::Ready(data);
|
||||
d.condvar.1.notify_all();
|
||||
}
|
||||
Err(err) => {
|
||||
thand.set_state(ResourceState::Error(Arc::new(err)));
|
||||
let mut d = untyped.write();
|
||||
d.state = ResourceState::Error(Arc::new(err));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let res: Arc<dyn ResourceStorage> = Arc::from(handle.clone());
|
||||
state.resources.insert(path.to_string(), res.clone());
|
||||
state.uuid_resources.insert(res.uuid(), res);
|
||||
|
||||
Ok(handle)
|
||||
Ok(handle.clone_untyped())
|
||||
} else {
|
||||
Err(RequestError::UnsupportedFileExtension(path.to_string()))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue