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 thiserror::Error;
|
||||||
use uuid::Uuid;
|
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.
|
/// A trait for type erased storage of a resource.
|
||||||
/// Implemented for [`ResHandle<T>`]
|
/// Implemented for [`ResHandle<T>`]
|
||||||
|
@ -26,6 +26,7 @@ pub trait ResourceStorage: Send + Sync + Any + 'static {
|
||||||
fn is_watched(&self) -> bool;
|
fn is_watched(&self) -> bool;
|
||||||
fn is_loaded(&self) -> bool;
|
fn is_loaded(&self) -> bool;
|
||||||
fn set_state(&self, new: ResourceState);
|
fn set_state(&self, new: ResourceState);
|
||||||
|
fn clone_untyped(&self) -> UntypedResHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[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
|
/// Loading resources is done asynchronously on a task spawned by `async-std`. You can use the
|
||||||
/// handle to check if the resource is loaded.
|
/// handle to check if the resource is loaded.
|
||||||
|
#[inline(always)]
|
||||||
pub fn request<T>(&self, path: &str) -> Result<ResHandle<T>, RequestError>
|
pub fn request<T>(&self, path: &str) -> Result<ResHandle<T>, RequestError>
|
||||||
where
|
where
|
||||||
T: ResourceData
|
T: ResourceData
|
||||||
{
|
{
|
||||||
let mut state = self.state_mut();
|
self.request_raw(path)
|
||||||
match state.resources.get(&path.to_string()) {
|
.map(|res| res.as_typed::<T>()
|
||||||
Some(res) => {
|
.expect("mismatched asset type, cannot downcast"))
|
||||||
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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request a resource without downcasting to a `ResHandle<T>`.
|
/// Request a resource without downcasting to a `ResHandle<T>`.
|
||||||
|
@ -177,11 +138,11 @@ impl ResourceManager {
|
||||||
/// let arc_any = res_arc.as_arc_any();
|
/// let arc_any = res_arc.as_arc_any();
|
||||||
/// let res: Arc<ResHandle<T>> = res.downcast::<ResHandle<T>>().expect("Failure to downcast resource");
|
/// 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();
|
let mut state = self.state_mut();
|
||||||
match state.resources.get(&path.to_string()) {
|
match state.resources.get(&path.to_string()) {
|
||||||
Some(res) => {
|
Some(res) => {
|
||||||
Ok(res.clone())
|
Ok(res.clone().clone_untyped())
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
if let Some(loader) = state.loaders.iter()
|
if let Some(loader) = state.loaders.iter()
|
||||||
|
@ -192,24 +153,29 @@ impl ResourceManager {
|
||||||
let res = loader.load(self.clone(), path);
|
let res = loader.load(self.clone(), path);
|
||||||
|
|
||||||
let handle = loader.create_erased_handle();
|
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 {
|
task::spawn(async move {
|
||||||
match res.await {
|
match res.await {
|
||||||
Ok(data) => {
|
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) => {
|
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());
|
let res: Arc<dyn ResourceStorage> = Arc::from(handle.clone());
|
||||||
|
state.resources.insert(path.to_string(), res.clone());
|
||||||
state.uuid_resources.insert(res.uuid(), res);
|
state.uuid_resources.insert(res.uuid(), res);
|
||||||
|
|
||||||
Ok(handle)
|
Ok(handle.clone_untyped())
|
||||||
} else {
|
} else {
|
||||||
Err(RequestError::UnsupportedFileExtension(path.to_string()))
|
Err(RequestError::UnsupportedFileExtension(path.to_string()))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue