mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
tidy up resource header content
- moved resource uuid to ResourceState::Ok
This commit is contained in:
@@ -1144,7 +1144,7 @@ pub trait SceneGraph: BaseSceneGraph {
|
||||
let mut nodes_to_delete = Vec::new();
|
||||
for (_, node) in self.traverse_iter(instance_root) {
|
||||
if let Some(resource) = node.resource() {
|
||||
let kind = resource.kind().clone();
|
||||
let kind = resource.kind();
|
||||
if let Some(model) = resource.state().data() {
|
||||
if !model
|
||||
.graph()
|
||||
@@ -1182,7 +1182,7 @@ pub trait SceneGraph: BaseSceneGraph {
|
||||
|
||||
// Step 2. Look for missing nodes and create appropriate instances for them.
|
||||
let mut model = resource.state();
|
||||
let model_kind = model.kind().clone();
|
||||
let model_kind = model.kind();
|
||||
if let Some(data) = model.data() {
|
||||
let resource_graph = data.graph();
|
||||
|
||||
@@ -1279,7 +1279,7 @@ pub trait SceneGraph: BaseSceneGraph {
|
||||
for node in self.linear_iter_mut() {
|
||||
if let Some(model) = node.resource() {
|
||||
let mut header = model.state();
|
||||
let model_kind = header.kind().clone();
|
||||
let model_kind = header.kind();
|
||||
if let Some(data) = header.data() {
|
||||
let resource_graph = data.graph();
|
||||
|
||||
|
||||
@@ -2563,7 +2563,7 @@ impl Engine {
|
||||
let mut state = self.resource_manager.state();
|
||||
for resource in state.resources().iter() {
|
||||
let data = resource.0.lock();
|
||||
if let ResourceState::Ok(ref data) = data.state {
|
||||
if let ResourceState::Ok { ref data, .. } = data.state {
|
||||
data.as_reflect(&mut |reflect| {
|
||||
if reflect.assembly_name() == plugin_assembly_name {
|
||||
resources_to_reload.insert(resource.clone());
|
||||
|
||||
@@ -1232,14 +1232,14 @@ impl MaterialResourceExtension for MaterialResource {
|
||||
let material_state = self.header();
|
||||
let kind = material_state.kind.clone();
|
||||
match material_state.state {
|
||||
ResourceState::Pending { .. } => MaterialResource::new_pending(Uuid::new_v4(), kind),
|
||||
ResourceState::Pending { .. } => MaterialResource::new_pending(kind),
|
||||
ResourceState::LoadError { ref error, .. } => {
|
||||
MaterialResource::new_load_error(Uuid::new_v4(), kind.clone(), error.clone())
|
||||
MaterialResource::new_load_error(kind.clone(), error.clone())
|
||||
}
|
||||
ResourceState::Ok(ref material) => MaterialResource::new_ok(
|
||||
ResourceState::Ok { ref data, .. } => MaterialResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
kind,
|
||||
ResourceDataAsAny::as_any(&**material)
|
||||
ResourceDataAsAny::as_any(&**data)
|
||||
.downcast_ref::<Material>()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
|
||||
@@ -355,7 +355,9 @@ impl SceneLoader {
|
||||
.filter(|res| {
|
||||
let state = self.resource_manager.state();
|
||||
let registry = state.resource_registry.lock();
|
||||
registry.uuid_to_path(res.resource_uuid()) == Some(&path)
|
||||
res.resource_uuid()
|
||||
.and_then(|uuid| registry.uuid_to_path(uuid))
|
||||
== Some(&path)
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -457,7 +457,7 @@ impl NodeTrait for Sound {
|
||||
Some(buffer) => {
|
||||
let header = buffer.header();
|
||||
match header.state {
|
||||
ResourceState::Pending { .. } | ResourceState::Ok(_) => Ok(()),
|
||||
ResourceState::Pending { .. } | ResourceState::Ok { .. } => Ok(()),
|
||||
ResourceState::LoadError { ref error, .. } => {
|
||||
match &error.0 {
|
||||
None => Err("Sound buffer is failed to load, the reason is unknown!"
|
||||
|
||||
@@ -562,8 +562,12 @@ impl TileBook {
|
||||
pub fn path(&self, registry: &ResourceRegistry) -> Option<PathBuf> {
|
||||
match self {
|
||||
TileBook::Empty => None,
|
||||
TileBook::TileSet(r) => registry.uuid_to_path_buf(r.header().resource_uuid),
|
||||
TileBook::Brush(r) => registry.uuid_to_path_buf(r.header().resource_uuid),
|
||||
TileBook::TileSet(r) => r
|
||||
.resource_uuid()
|
||||
.and_then(|uuid| registry.uuid_to_path_buf(uuid)),
|
||||
TileBook::Brush(r) => r
|
||||
.resource_uuid()
|
||||
.and_then(|uuid| registry.uuid_to_path_buf(uuid)),
|
||||
}
|
||||
}
|
||||
/// True if the resource is external and its `change_count` is not zero.
|
||||
@@ -585,8 +589,11 @@ impl TileBook {
|
||||
TileBook::Empty => Ok(()),
|
||||
TileBook::TileSet(r) => {
|
||||
if r.header().kind.is_external() && r.data_ref().change_flag.needs_save() {
|
||||
let result =
|
||||
r.save(®istry.uuid_to_path_buf(r.header().resource_uuid).unwrap());
|
||||
let result = r.save(
|
||||
®istry
|
||||
.uuid_to_path_buf(r.resource_uuid().unwrap())
|
||||
.unwrap(),
|
||||
);
|
||||
if result.is_ok() {
|
||||
r.data_ref().change_flag.reset();
|
||||
}
|
||||
@@ -597,8 +604,11 @@ impl TileBook {
|
||||
}
|
||||
TileBook::Brush(r) => {
|
||||
if r.header().kind.is_external() && r.data_ref().change_flag.needs_save() {
|
||||
let result =
|
||||
r.save(®istry.uuid_to_path_buf(r.header().resource_uuid).unwrap());
|
||||
let result = r.save(
|
||||
®istry
|
||||
.uuid_to_path_buf(r.resource_uuid().unwrap())
|
||||
.unwrap(),
|
||||
);
|
||||
if result.is_ok() {
|
||||
r.data_ref().change_flag.reset();
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ impl ResourceGraphNode {
|
||||
let mut dependent_resources = FxHashSet::default();
|
||||
|
||||
let header = resource.0.lock();
|
||||
if let ResourceState::Ok(ref resource_data) = header.state {
|
||||
(**resource_data).as_reflect(&mut |entity| {
|
||||
if let ResourceState::Ok { ref data, .. } = header.state {
|
||||
(**data).as_reflect(&mut |entity| {
|
||||
collect_used_resources(entity, &mut dependent_resources);
|
||||
});
|
||||
}
|
||||
@@ -131,16 +131,9 @@ mod test {
|
||||
#[test]
|
||||
fn resource_graph_node_pretty_print() {
|
||||
let mut s = String::new();
|
||||
let mut node = ResourceGraphNode::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
let node2 = ResourceGraphNode::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
let mut node =
|
||||
ResourceGraphNode::new(&UntypedResource::new_pending(ResourceKind::External));
|
||||
let node2 = ResourceGraphNode::new(&UntypedResource::new_pending(ResourceKind::External));
|
||||
node.children.push(node2);
|
||||
node.pretty_print(1, &mut s);
|
||||
|
||||
@@ -169,18 +162,13 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn resource_dependency_pretty_print() {
|
||||
let mut graph = ResourceDependencyGraph::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
let mut graph =
|
||||
ResourceDependencyGraph::new(&UntypedResource::new_pending(ResourceKind::External));
|
||||
graph
|
||||
.root
|
||||
.children
|
||||
.push(ResourceGraphNode::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
)));
|
||||
|
||||
let s = graph.pretty_print();
|
||||
@@ -189,18 +177,13 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn resource_dependency_for_each() {
|
||||
let mut graph = ResourceDependencyGraph::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
let mut graph =
|
||||
ResourceDependencyGraph::new(&UntypedResource::new_pending(ResourceKind::External));
|
||||
graph
|
||||
.root
|
||||
.children
|
||||
.push(ResourceGraphNode::new(&UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
)));
|
||||
|
||||
let mut uuids = Vec::new();
|
||||
|
||||
+26
-26
@@ -125,12 +125,12 @@ impl<T> ResourceHeaderGuard<'_, T>
|
||||
where
|
||||
T: TypedResourceData,
|
||||
{
|
||||
pub fn kind(&self) -> &ResourceKind {
|
||||
&self.guard.kind
|
||||
pub fn kind(&self) -> ResourceKind {
|
||||
self.guard.kind
|
||||
}
|
||||
|
||||
pub fn data(&mut self) -> Option<&mut T> {
|
||||
if let ResourceState::Ok(ref mut data) = self.guard.state {
|
||||
if let ResourceState::Ok { ref mut data, .. } = self.guard.state {
|
||||
ResourceDataAsAny::as_any_mut(&mut **data).downcast_mut::<T>()
|
||||
} else {
|
||||
None
|
||||
@@ -138,7 +138,7 @@ where
|
||||
}
|
||||
|
||||
pub fn data_ref(&self) -> Option<&T> {
|
||||
if let ResourceState::Ok(ref data) = self.guard.state {
|
||||
if let ResourceState::Ok { ref data, .. } = self.guard.state {
|
||||
ResourceDataAsAny::as_any(&**data).downcast_ref::<T>()
|
||||
} else {
|
||||
None
|
||||
@@ -184,14 +184,15 @@ where
|
||||
let mut untyped = UntypedResource::default();
|
||||
if untyped.visit(name, visitor).is_ok() {
|
||||
let untyped_data_type = untyped.type_uuid();
|
||||
if untyped_data_type == <T as TypeUuidProvider>::type_uuid() {
|
||||
if untyped_data_type == Some(<T as TypeUuidProvider>::type_uuid()) {
|
||||
self.untyped = untyped;
|
||||
return Ok(());
|
||||
} else {
|
||||
Log::err(format!(
|
||||
"Unable to deserialize untyped resource into its typed \
|
||||
version, because types do not match! Untyped resource has \
|
||||
{untyped_data_type} type, but the required type is {}",
|
||||
{:?} type, but the required type is {}",
|
||||
untyped_data_type,
|
||||
<T as TypeUuidProvider>::type_uuid(),
|
||||
))
|
||||
}
|
||||
@@ -242,13 +243,9 @@ where
|
||||
{
|
||||
/// Creates new resource in pending state.
|
||||
#[inline]
|
||||
pub fn new_pending(resource_uuid: Uuid, kind: ResourceKind) -> Self {
|
||||
pub fn new_pending(kind: ResourceKind) -> Self {
|
||||
Self {
|
||||
untyped: UntypedResource::new_pending(
|
||||
resource_uuid,
|
||||
kind,
|
||||
<T as TypeUuidProvider>::type_uuid(),
|
||||
),
|
||||
untyped: UntypedResource::new_pending(kind),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -264,14 +261,9 @@ where
|
||||
|
||||
/// Creates new resource in error state.
|
||||
#[inline]
|
||||
pub fn new_load_error(resource_uuid: Uuid, kind: ResourceKind, error: LoadError) -> Self {
|
||||
pub fn new_load_error(kind: ResourceKind, error: LoadError) -> Self {
|
||||
Self {
|
||||
untyped: UntypedResource::new_load_error(
|
||||
resource_uuid,
|
||||
kind,
|
||||
error,
|
||||
<T as TypeUuidProvider>::type_uuid(),
|
||||
),
|
||||
untyped: UntypedResource::new_load_error(kind, error),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -315,7 +307,7 @@ where
|
||||
/// Returns true if the resource is fully loaded and ready for use.
|
||||
#[inline]
|
||||
pub fn is_ok(&self) -> bool {
|
||||
matches!(self.untyped.0.lock().state, ResourceState::Ok(_))
|
||||
matches!(self.untyped.0.lock().state, ResourceState::Ok { .. })
|
||||
}
|
||||
|
||||
/// Returns true if the resource is failed to load.
|
||||
@@ -342,6 +334,11 @@ where
|
||||
self.untyped.kind()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resource_uuid(&self) -> Option<Uuid> {
|
||||
self.untyped.resource_uuid()
|
||||
}
|
||||
|
||||
/// Sets a new kind of the resource.
|
||||
#[inline]
|
||||
pub fn set_path(&mut self, new_kind: ResourceKind) {
|
||||
@@ -407,7 +404,10 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn from(untyped: UntypedResource) -> Self {
|
||||
assert_eq!(untyped.type_uuid(), <T as TypeUuidProvider>::type_uuid());
|
||||
assert_eq!(
|
||||
untyped.type_uuid(),
|
||||
Some(<T as TypeUuidProvider>::type_uuid())
|
||||
);
|
||||
Self {
|
||||
untyped,
|
||||
phantom: Default::default(),
|
||||
@@ -456,7 +456,7 @@ where
|
||||
#[inline]
|
||||
pub fn as_loaded_ref(&self) -> Option<&T> {
|
||||
match self.guard.state {
|
||||
ResourceState::Ok(ref data) => ResourceDataAsAny::as_any(&**data).downcast_ref(),
|
||||
ResourceState::Ok { ref data, .. } => ResourceDataAsAny::as_any(&**data).downcast_ref(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -464,7 +464,7 @@ where
|
||||
#[inline]
|
||||
pub fn as_loaded_mut(&mut self) -> Option<&mut T> {
|
||||
match self.guard.state {
|
||||
ResourceState::Ok(ref mut data) => {
|
||||
ResourceState::Ok { ref mut data, .. } => {
|
||||
ResourceDataAsAny::as_any_mut(&mut **data).downcast_mut()
|
||||
}
|
||||
_ => None,
|
||||
@@ -492,7 +492,7 @@ where
|
||||
self.guard.kind
|
||||
)
|
||||
}
|
||||
ResourceState::Ok(ref data) => data.fmt(f),
|
||||
ResourceState::Ok { ref data, .. } => data.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -517,7 +517,7 @@ where
|
||||
self.guard.kind
|
||||
)
|
||||
}
|
||||
ResourceState::Ok(ref data) => ResourceDataAsAny::as_any(&**data)
|
||||
ResourceState::Ok { ref data, .. } => ResourceDataAsAny::as_any(&**data)
|
||||
.downcast_ref()
|
||||
.expect("Type mismatch!"),
|
||||
}
|
||||
@@ -543,7 +543,7 @@ where
|
||||
header.kind
|
||||
)
|
||||
}
|
||||
ResourceState::Ok(ref mut data) => ResourceDataAsAny::as_any_mut(&mut **data)
|
||||
ResourceState::Ok { ref mut data, .. } => ResourceDataAsAny::as_any_mut(&mut **data)
|
||||
.downcast_mut()
|
||||
.expect("Type mismatch!"),
|
||||
}
|
||||
|
||||
+61
-119
@@ -32,7 +32,6 @@ use crate::{
|
||||
parking_lot::{Mutex, MutexGuard},
|
||||
task::TaskPool,
|
||||
watcher::FileSystemWatcher,
|
||||
TypeUuidProvider,
|
||||
},
|
||||
entry::{TimedEntry, DEFAULT_RESOURCE_LIFETIME},
|
||||
event::{ResourceEvent, ResourceEventBroadcaster},
|
||||
@@ -327,11 +326,6 @@ impl ResourceManager {
|
||||
/// Actual resource state can be fetched by [`Resource::state`] method. If you know for sure that the resource
|
||||
/// is already loaded, then you can use [`Resource::data_ref`] to obtain a reference to the actual resource data.
|
||||
/// Keep in mind, that this method will panic if the resource non in `Ok` state.
|
||||
///
|
||||
/// ## Panic
|
||||
///
|
||||
/// This method will panic, if type UUID of `T` does not match the actual type UUID of the resource. If this
|
||||
/// is undesirable, use [`Self::try_request`] instead.
|
||||
pub fn request<T>(&self, path: impl AsRef<Path>) -> Resource<T>
|
||||
where
|
||||
T: TypedResourceData,
|
||||
@@ -342,28 +336,6 @@ impl ResourceManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// The same as [`Self::request`], but returns [`None`] if type UUID of `T` does not match the actual type UUID
|
||||
/// of the resource.
|
||||
///
|
||||
/// ## Panic
|
||||
///
|
||||
/// This method does not panic.
|
||||
pub fn try_request<T>(&self, path: impl AsRef<Path>) -> Option<Resource<T>>
|
||||
where
|
||||
T: TypedResourceData,
|
||||
{
|
||||
let untyped = self.state().request(path);
|
||||
let actual_type_uuid = untyped.type_uuid();
|
||||
if actual_type_uuid == <T as TypeUuidProvider>::type_uuid() {
|
||||
Some(Resource {
|
||||
untyped,
|
||||
phantom: PhantomData::<T>,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as [`Self::request`], but returns untyped resource.
|
||||
pub fn request_untyped<P>(&self, path: P) -> UntypedResource
|
||||
where
|
||||
@@ -389,12 +361,14 @@ impl ResourceManager {
|
||||
F: FnMut(&mut dyn ResourceData, &Path) -> bool,
|
||||
{
|
||||
let path = path.as_ref().to_owned();
|
||||
let resource_uuid = resource.resource_uuid();
|
||||
let resource_uuid = resource
|
||||
.resource_uuid()
|
||||
.ok_or(ResourceRegistrationError::InvalidState)?;
|
||||
|
||||
let mut state = self.state();
|
||||
if let Some(resource) = state.find(resource_uuid) {
|
||||
let resource_state = resource.0.lock();
|
||||
if let ResourceState::Ok(_) = resource_state.state {
|
||||
if let ResourceState::Ok { .. } = resource_state.state {
|
||||
return Err(ResourceRegistrationError::AlreadyRegistered);
|
||||
}
|
||||
}
|
||||
@@ -403,14 +377,16 @@ impl ResourceManager {
|
||||
|
||||
let mut header = resource.0.lock();
|
||||
header.kind.make_external();
|
||||
if let ResourceState::Ok(ref mut data) = header.state {
|
||||
if let ResourceState::Ok {
|
||||
ref mut data,
|
||||
resource_uuid,
|
||||
..
|
||||
} = header.state
|
||||
{
|
||||
if !on_register(&mut **data, path.as_ref()) {
|
||||
Err(ResourceRegistrationError::UnableToRegister)
|
||||
} else {
|
||||
state
|
||||
.resource_registry
|
||||
.lock()
|
||||
.register(header.resource_uuid, path);
|
||||
state.resource_registry.lock().register(resource_uuid, path);
|
||||
drop(header);
|
||||
state.push(resource);
|
||||
Ok(())
|
||||
@@ -426,12 +402,16 @@ impl ResourceManager {
|
||||
resource: UntypedResource,
|
||||
new_path: impl AsRef<Path>,
|
||||
) -> Result<(), FileError> {
|
||||
let resource_uuid = resource
|
||||
.resource_uuid()
|
||||
.ok_or_else(|| FileError::Custom("Unable to move non-loaded resource!".to_string()))?;
|
||||
|
||||
let new_path = new_path.as_ref().to_owned();
|
||||
let io = self.state().resource_io.clone();
|
||||
let registry = self.state().resource_registry.clone();
|
||||
let existing_path = registry
|
||||
.lock()
|
||||
.uuid_to_path(resource.resource_uuid())
|
||||
.uuid_to_path(resource_uuid)
|
||||
.map(|path| path.to_path_buf())
|
||||
.ok_or_else(|| FileError::Custom("Cannot move embedded resource!".to_string()))?;
|
||||
|
||||
@@ -604,10 +584,10 @@ impl ResourceManagerState {
|
||||
if resource.value.use_count() <= 1 {
|
||||
resource.time_to_live -= dt;
|
||||
if resource.time_to_live <= 0.0 {
|
||||
if let Some(path) = self
|
||||
.resource_registry
|
||||
.lock()
|
||||
.uuid_to_path(resource.0.lock().resource_uuid)
|
||||
let registry = self.resource_registry.lock();
|
||||
let resource_uuid = resource.resource_uuid();
|
||||
if let Some(path) =
|
||||
resource_uuid.and_then(|resource_uuid| registry.uuid_to_path(resource_uuid))
|
||||
{
|
||||
Log::info(format!(
|
||||
"Resource {} destroyed because it is not used anymore!",
|
||||
@@ -671,16 +651,21 @@ impl ResourceManagerState {
|
||||
pub fn find(&self, uuid: Uuid) -> Option<&UntypedResource> {
|
||||
self.resources
|
||||
.iter()
|
||||
.find(|entry| entry.value.resource_uuid() == uuid)
|
||||
.find(|entry| entry.value.resource_uuid() == Some(uuid))
|
||||
.map(|entry| &entry.value)
|
||||
}
|
||||
|
||||
pub fn find_by_path(&self, path: &Path) -> Option<&UntypedResource> {
|
||||
let registry = self.resource_registry.lock();
|
||||
self.resources
|
||||
.iter()
|
||||
.find(|entry| registry.uuid_to_path(entry.value.resource_uuid()) == Some(path))
|
||||
.map(|entry| &entry.value)
|
||||
self.resources.iter().find_map(|entry| {
|
||||
let header = entry.value.0.lock();
|
||||
if let ResourceState::Ok { resource_uuid, .. } = header.state {
|
||||
if registry.uuid_to_path(resource_uuid) == Some(path) {
|
||||
return Some(&entry.value);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns total amount of resources in the container.
|
||||
@@ -718,7 +703,7 @@ impl ResourceManagerState {
|
||||
/// Returns total amount of completely loaded resources.
|
||||
pub fn count_loaded_resources(&self) -> usize {
|
||||
self.resources.iter().fold(0, |counter, resource| {
|
||||
if let ResourceState::Ok(_) = resource.0.lock().state {
|
||||
if let ResourceState::Ok { .. } = resource.0.lock().state {
|
||||
counter + 1
|
||||
} else {
|
||||
counter
|
||||
@@ -743,11 +728,13 @@ impl ResourceManagerState {
|
||||
self.find_or_load(ResourcePath::Explicit(path.as_ref().to_path_buf()))
|
||||
}
|
||||
|
||||
/// Tries to load a resource by a unique identifier. The identifier must not be a zero-uuid,
|
||||
/// otherwise this method will panic!
|
||||
pub fn request_by_uuid(&mut self, resource_uuid: Uuid) -> UntypedResource {
|
||||
if let Some(built_in_resource) = self
|
||||
.built_in_resources
|
||||
.values()
|
||||
.find(|r| r.resource.resource_uuid() == resource_uuid)
|
||||
.find(|r| r.resource.resource_uuid() == Some(resource_uuid))
|
||||
{
|
||||
return built_in_resource.resource.clone();
|
||||
}
|
||||
@@ -763,14 +750,12 @@ impl ResourceManagerState {
|
||||
match header.state {
|
||||
ResourceState::Pending { ref path, .. }
|
||||
| ResourceState::LoadError { ref path, .. } => path == path_to_search,
|
||||
ResourceState::Ok(_) => match path_to_search {
|
||||
ResourceState::Ok { resource_uuid, .. } => match path_to_search {
|
||||
ResourcePath::Explicit(fs_path) => {
|
||||
self.resource_registry
|
||||
.lock()
|
||||
.uuid_to_path(header.resource_uuid)
|
||||
self.resource_registry.lock().uuid_to_path(resource_uuid)
|
||||
== Some(fs_path)
|
||||
}
|
||||
ResourcePath::Implicit(uuid) => &header.resource_uuid == uuid,
|
||||
ResourcePath::Implicit(uuid) => &resource_uuid == uuid,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -781,8 +766,7 @@ impl ResourceManagerState {
|
||||
match self.find_by_resource_path(&path) {
|
||||
Some(existing) => existing.clone(),
|
||||
None => {
|
||||
let resource =
|
||||
UntypedResource::new_pending(Uuid::nil(), ResourceKind::External, Uuid::nil());
|
||||
let resource = UntypedResource::new_pending(ResourceKind::External);
|
||||
self.spawn_loading_task(path, resource.clone(), false);
|
||||
self.push(resource.clone());
|
||||
resource
|
||||
@@ -791,6 +775,10 @@ impl ResourceManagerState {
|
||||
}
|
||||
|
||||
fn spawn_loading_task(&self, path: ResourcePath, resource: UntypedResource, reload: bool) {
|
||||
if let ResourcePath::Implicit(ref uuid) = path {
|
||||
assert_ne!(*uuid, Uuid::nil());
|
||||
}
|
||||
|
||||
let event_broadcaster = self.event_broadcaster.clone();
|
||||
let loaders = self.loaders.clone();
|
||||
let registry = self.resource_registry.clone();
|
||||
@@ -843,11 +831,12 @@ impl ResourceManagerState {
|
||||
// Separate scope to keep mutex locking time at minimum.
|
||||
{
|
||||
let mut mutex_guard = resource.0.lock();
|
||||
mutex_guard.resource_uuid =
|
||||
registry.lock().path_to_uuid(&fs_path).unwrap();
|
||||
mutex_guard.type_uuid = data.type_uuid();
|
||||
let resource_uuid = registry.lock().path_to_uuid(&fs_path).unwrap();
|
||||
assert!(mutex_guard.kind.is_external());
|
||||
mutex_guard.state.commit(ResourceState::Ok(data));
|
||||
mutex_guard.state.commit(ResourceState::Ok {
|
||||
data,
|
||||
resource_uuid,
|
||||
});
|
||||
}
|
||||
|
||||
event_broadcaster.broadcast_loaded_or_reloaded(resource, reload);
|
||||
@@ -886,8 +875,8 @@ impl ResourceManagerState {
|
||||
drop(header);
|
||||
self.spawn_loading_task(path, resource, true)
|
||||
}
|
||||
ResourceState::Ok(_) => {
|
||||
let path = ResourcePath::Implicit(header.resource_uuid);
|
||||
ResourceState::Ok { resource_uuid, .. } => {
|
||||
let path = ResourcePath::Implicit(resource_uuid);
|
||||
drop(header);
|
||||
self.spawn_loading_task(path, resource, true)
|
||||
}
|
||||
@@ -941,7 +930,7 @@ impl ResourceManagerState {
|
||||
if let Some(position) = self
|
||||
.resources
|
||||
.iter()
|
||||
.position(|entry| entry.value.resource_uuid() == uuid)
|
||||
.position(|entry| entry.value.resource_uuid() == Some(uuid))
|
||||
{
|
||||
self.resources.remove(position);
|
||||
}
|
||||
@@ -1012,17 +1001,8 @@ mod test {
|
||||
|
||||
let cx = ResourceWaitContext {
|
||||
resources: vec![
|
||||
UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
),
|
||||
UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
Uuid::default(),
|
||||
),
|
||||
UntypedResource::new_pending(ResourceKind::External),
|
||||
UntypedResource::new_load_error(ResourceKind::External, Default::default()),
|
||||
],
|
||||
};
|
||||
assert!(!cx.is_all_loaded());
|
||||
@@ -1062,16 +1042,10 @@ mod test {
|
||||
assert_eq!(state.count_registered_resources(), 0);
|
||||
assert_eq!(state.len(), 0);
|
||||
|
||||
state.push(UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
state.push(UntypedResource::new_pending(ResourceKind::External));
|
||||
state.push(UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
Uuid::default(),
|
||||
));
|
||||
state.push(UntypedResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
@@ -1091,16 +1065,10 @@ mod test {
|
||||
|
||||
assert_eq!(state.loading_progress(), 100);
|
||||
|
||||
state.push(UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
state.push(UntypedResource::new_pending(ResourceKind::External));
|
||||
state.push(UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
Uuid::default(),
|
||||
));
|
||||
state.push(UntypedResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
@@ -1118,9 +1086,7 @@ mod test {
|
||||
assert!(state.find_by_path(Path::new("foo.txt")).is_none());
|
||||
|
||||
let path = PathBuf::from("test.txt");
|
||||
let type_uuid = Uuid::default();
|
||||
let resource =
|
||||
UntypedResource::new_pending(Uuid::new_v4(), ResourceKind::External, type_uuid);
|
||||
let resource = UntypedResource::new_pending(ResourceKind::External);
|
||||
state.push(resource.clone());
|
||||
|
||||
assert_eq!(state.find_by_path(&path), Some(&resource));
|
||||
@@ -1132,14 +1098,8 @@ mod test {
|
||||
|
||||
assert_eq!(state.resources(), Vec::new());
|
||||
|
||||
let r1 =
|
||||
UntypedResource::new_pending(Uuid::new_v4(), ResourceKind::External, Uuid::default());
|
||||
let r2 = UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
Uuid::default(),
|
||||
);
|
||||
let r1 = UntypedResource::new_pending(ResourceKind::External);
|
||||
let r2 = UntypedResource::new_load_error(ResourceKind::External, Default::default());
|
||||
let r3 = UntypedResource::new_ok(Uuid::new_v4(), ResourceKind::Embedded, Stub {});
|
||||
state.push(r1.clone());
|
||||
state.push(r2.clone());
|
||||
@@ -1153,11 +1113,7 @@ mod test {
|
||||
fn resource_manager_state_destroy_unused_resources() {
|
||||
let mut state = new_resource_manager();
|
||||
|
||||
state.push(UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::default(),
|
||||
));
|
||||
state.push(UntypedResource::new_pending(ResourceKind::External));
|
||||
assert_eq!(state.len(), 1);
|
||||
|
||||
state.destroy_unused_resources();
|
||||
@@ -1168,14 +1124,8 @@ mod test {
|
||||
fn resource_manager_state_request() {
|
||||
let mut state = new_resource_manager();
|
||||
let path = PathBuf::from("test.txt");
|
||||
let type_uuid = Uuid::default();
|
||||
|
||||
let resource = UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
type_uuid,
|
||||
);
|
||||
let resource = UntypedResource::new_load_error(ResourceKind::External, Default::default());
|
||||
state.push(resource.clone());
|
||||
|
||||
let res = state.request(path);
|
||||
@@ -1185,7 +1135,6 @@ mod test {
|
||||
let res = state.request(path.clone());
|
||||
|
||||
assert_eq!(res.kind(), ResourceKind::External);
|
||||
assert_eq!(res.type_uuid(), type_uuid);
|
||||
assert!(!res.is_loading());
|
||||
}
|
||||
|
||||
@@ -1194,12 +1143,7 @@ mod test {
|
||||
let mut state = new_resource_manager();
|
||||
state.loaders.lock().set(Stub {});
|
||||
|
||||
let resource = UntypedResource::new_load_error(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Default::default(),
|
||||
Uuid::default(),
|
||||
);
|
||||
let resource = UntypedResource::new_load_error(ResourceKind::External, Default::default());
|
||||
state.push(resource.clone());
|
||||
|
||||
assert!(!state.try_reload_resource_from_path(Path::new("foo.txt")));
|
||||
@@ -1231,10 +1175,8 @@ mod test {
|
||||
fn resource_manager_register() {
|
||||
let manager = ResourceManager::new(Arc::new(Default::default()));
|
||||
let path = PathBuf::from("test.txt");
|
||||
let type_uuid = Uuid::default();
|
||||
|
||||
let resource =
|
||||
UntypedResource::new_pending(Uuid::new_v4(), ResourceKind::External, type_uuid);
|
||||
let resource = UntypedResource::new_pending(ResourceKind::External);
|
||||
let res = manager.register(resource.clone(), path.clone(), |_, _| true);
|
||||
assert!(res.is_err());
|
||||
|
||||
|
||||
+62
-16
@@ -20,11 +20,13 @@
|
||||
|
||||
//! A module that handles resource states.
|
||||
|
||||
use crate::untyped::ResourceKind;
|
||||
use crate::{
|
||||
core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*},
|
||||
manager::ResourceManager,
|
||||
ResourceData, ResourceLoadError,
|
||||
};
|
||||
use fyrox_core::warn;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -108,6 +110,13 @@ impl Default for ResourcePath {
|
||||
/// Resources do not store their paths to respective files in the file system, instead resource only
|
||||
/// stores their unique identifiers (UUID). Use [`crate::registry::ResourceRegistry`] to get a path
|
||||
/// associated with the resource uuid.
|
||||
///
|
||||
/// ## UUID
|
||||
///
|
||||
/// Resource UUID is available only if the resource is fully loaded. This is because there's no way
|
||||
/// to get the UUID earlier: the UUID is stored in a metadata file which exists only if the resource
|
||||
/// is present. It is somewhat possible to get a UUID when a resource is failed to load, but not in
|
||||
/// 100% cases.
|
||||
#[derive(Debug, Reflect)]
|
||||
pub enum ResourceState {
|
||||
/// Resource is loading from external resource or in the queue to load.
|
||||
@@ -130,7 +139,12 @@ pub enum ResourceState {
|
||||
error: LoadError,
|
||||
},
|
||||
/// Actual resource data when it is fully loaded.
|
||||
Ok(Box<dyn ResourceData>),
|
||||
Ok {
|
||||
/// Unique id of the resource.
|
||||
resource_uuid: Uuid,
|
||||
/// Actual data of the resource.
|
||||
data: Box<dyn ResourceData>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Default for ResourceState {
|
||||
@@ -150,12 +164,20 @@ impl Drop for ResourceState {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for ResourceState {
|
||||
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
|
||||
impl ResourceState {
|
||||
pub fn visit(&mut self, kind: ResourceKind, name: &str, visitor: &mut Visitor) -> VisitResult {
|
||||
if visitor.is_reading() {
|
||||
let mut type_uuid = Uuid::default();
|
||||
type_uuid.visit("TypeUuid", visitor)?;
|
||||
|
||||
let mut resource_uuid = Uuid::default();
|
||||
if resource_uuid.visit("ResourceUuid", visitor).is_err() {
|
||||
warn!(
|
||||
"A resource of type {type_uuid} has no uuid! It looks like a resource in \
|
||||
the old format; trying to read it..."
|
||||
);
|
||||
}
|
||||
|
||||
let resource_manager = visitor.blackboard.get::<ResourceManager>().expect(
|
||||
"Resource data constructor container must be \
|
||||
provided when serializing resources!",
|
||||
@@ -167,25 +189,43 @@ impl Visit for ResourceState {
|
||||
.try_create(&type_uuid)
|
||||
{
|
||||
drop(resource_manager_state);
|
||||
instance.visit(name, visitor)?;
|
||||
*self = Self::Ok(instance);
|
||||
Ok(())
|
||||
|
||||
if kind == ResourceKind::Embedded {
|
||||
instance.visit(name, visitor)?;
|
||||
}
|
||||
|
||||
*self = Self::Ok {
|
||||
resource_uuid,
|
||||
data: instance,
|
||||
};
|
||||
} else {
|
||||
Err(VisitError::User(format!(
|
||||
return Err(VisitError::User(format!(
|
||||
"There's no constructor registered for type {type_uuid}!"
|
||||
)))
|
||||
)));
|
||||
}
|
||||
} else if let Self::Ok(instance) = self {
|
||||
instance.visit(name, visitor)?;
|
||||
|
||||
Ok(())
|
||||
} else if let Self::Ok {
|
||||
resource_uuid,
|
||||
data,
|
||||
} = self
|
||||
{
|
||||
resource_uuid.visit("ResourceUuid", visitor)?;
|
||||
|
||||
let mut type_uuid = data.type_uuid();
|
||||
type_uuid.visit("TypeUuid", visitor)?;
|
||||
|
||||
if kind == ResourceKind::Embedded {
|
||||
data.visit(name, visitor)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
// Do not save other variants, because they're needed only for runtime purposes.
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResourceState {
|
||||
/// Creates new resource in pending state.
|
||||
#[inline]
|
||||
pub fn new_pending() -> Self {
|
||||
@@ -203,8 +243,11 @@ impl ResourceState {
|
||||
|
||||
/// Creates new resource in ok (resource with data) state.
|
||||
#[inline]
|
||||
pub fn new_ok<T: ResourceData>(data: T) -> Self {
|
||||
Self::Ok(Box::new(data))
|
||||
pub fn new_ok<T: ResourceData>(resource_uuid: Uuid, data: T) -> Self {
|
||||
Self::Ok {
|
||||
resource_uuid,
|
||||
data: Box::new(data),
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether the resource is still loading or not.
|
||||
@@ -240,8 +283,11 @@ impl ResourceState {
|
||||
}
|
||||
|
||||
/// Changes internal state to [`ResourceState::Ok`]
|
||||
pub fn commit_ok<T: ResourceData>(&mut self, data: T) {
|
||||
self.commit(ResourceState::Ok(Box::new(data)))
|
||||
pub fn commit_ok<T: ResourceData>(&mut self, resource_uuid: Uuid, data: T) {
|
||||
self.commit(ResourceState::Ok {
|
||||
resource_uuid,
|
||||
data: Box::new(data),
|
||||
})
|
||||
}
|
||||
|
||||
/// Changes internal state to [`ResourceState::LoadError`].
|
||||
|
||||
@@ -87,7 +87,7 @@ fn guess_uuid(region: &mut RegionGuard) -> Uuid {
|
||||
}
|
||||
|
||||
/// Kind of a resource. It defines how the resource manager will treat a resource content on serialization.
|
||||
#[derive(Default, Reflect, Debug, Visit, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Default, Reflect, Debug, Visit, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ResourceKind {
|
||||
/// The content of embedded resources will be fully serialized.
|
||||
#[default]
|
||||
@@ -155,10 +155,6 @@ impl Display for ResourceKind {
|
||||
/// its kind, etc.
|
||||
#[derive(Reflect, Debug)]
|
||||
pub struct ResourceHeader {
|
||||
/// Unique id of a resource.
|
||||
pub resource_uuid: Uuid,
|
||||
/// UUID of the internal data type.
|
||||
pub type_uuid: Uuid,
|
||||
/// Kind of the resource. See [`ResourceKind`] for more info.
|
||||
pub kind: ResourceKind,
|
||||
/// Actual state of the resource. See [`ResourceState`] for more info.
|
||||
@@ -216,7 +212,11 @@ impl Visit for ResourceHeader {
|
||||
|
||||
instance.visit("Details", &mut region)?;
|
||||
|
||||
self.state = ResourceState::Ok(instance);
|
||||
self.state = ResourceState::Ok {
|
||||
data: instance,
|
||||
// The old format does not contain an uuid.
|
||||
resource_uuid: Uuid::nil(),
|
||||
};
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
@@ -232,27 +232,18 @@ impl Visit for ResourceHeader {
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
if region.is_reading() {
|
||||
let mut old_kind = OldResourceKind::Embedded;
|
||||
if old_kind.visit("Kind", &mut region).is_ok() {
|
||||
if let OldResourceKind::External(path) = old_kind {
|
||||
self.old_format_path = Some(path);
|
||||
} else {
|
||||
let mut old_kind = OldResourceKind::Embedded;
|
||||
if old_kind.visit("Kind", &mut region).is_ok() {
|
||||
if let OldResourceKind::External(path) = old_kind {
|
||||
self.old_format_path = Some(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.kind.visit("Kind", &mut region)?;
|
||||
self.type_uuid.visit("TypeUuid", &mut region)?;
|
||||
|
||||
// Backward compatibility.
|
||||
let _ = self.resource_uuid.visit("ResourceUuid", &mut region);
|
||||
|
||||
if self.kind == ResourceKind::Embedded {
|
||||
self.state.visit("State", &mut region)?;
|
||||
}
|
||||
self.state.visit(self.kind, "State", &mut region)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -306,20 +297,21 @@ impl Visit for UntypedResource {
|
||||
self.0.visit(name, visitor)?;
|
||||
|
||||
// Try to restore the shallow handle on deserialization for external resources.
|
||||
if visitor.is_reading() && !self.is_embedded() {
|
||||
let resource_manager = visitor
|
||||
.blackboard
|
||||
.get::<ResourceManager>()
|
||||
.expect("Resource manager must be available when deserializing resources!");
|
||||
|
||||
if visitor.is_reading() {
|
||||
let inner_lock = self.0.lock();
|
||||
let resource_uuid = inner_lock.resource_uuid;
|
||||
if let Some(old_format_path) = inner_lock.old_format_path.clone() {
|
||||
drop(inner_lock);
|
||||
self.0 = resource_manager.request_untyped(old_format_path).0;
|
||||
} else {
|
||||
drop(inner_lock);
|
||||
self.0 = resource_manager.request_by_uuid(resource_uuid).0;
|
||||
if inner_lock.kind == ResourceKind::External {
|
||||
let resource_manager = visitor
|
||||
.blackboard
|
||||
.get::<ResourceManager>()
|
||||
.expect("Resource manager must be available when deserializing resources!");
|
||||
|
||||
if let Some(old_format_path) = inner_lock.old_format_path.clone() {
|
||||
drop(inner_lock);
|
||||
self.0 = resource_manager.request_untyped(old_format_path).0;
|
||||
} else if let ResourceState::Ok { resource_uuid, .. } = inner_lock.state {
|
||||
drop(inner_lock);
|
||||
self.0 = resource_manager.request_by_uuid(resource_uuid).0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,9 +322,7 @@ impl Visit for UntypedResource {
|
||||
impl Default for UntypedResource {
|
||||
fn default() -> Self {
|
||||
Self(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid: Default::default(),
|
||||
kind: Default::default(),
|
||||
type_uuid: Default::default(),
|
||||
state: ResourceState::new_load_error(
|
||||
Default::default(),
|
||||
LoadError::new("Default resource state of unknown type."),
|
||||
@@ -364,11 +354,9 @@ impl Hash for UntypedResource {
|
||||
|
||||
impl UntypedResource {
|
||||
/// Creates new untyped resource in pending state using the given path and type uuid.
|
||||
pub fn new_pending(resource_uuid: Uuid, kind: ResourceKind, type_uuid: Uuid) -> Self {
|
||||
pub fn new_pending(kind: ResourceKind) -> Self {
|
||||
Self(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid,
|
||||
kind,
|
||||
type_uuid,
|
||||
state: ResourceState::new_pending(),
|
||||
old_format_path: None,
|
||||
})))
|
||||
@@ -381,37 +369,36 @@ impl UntypedResource {
|
||||
T: ResourceData,
|
||||
{
|
||||
Self(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid,
|
||||
kind,
|
||||
type_uuid: data.type_uuid(),
|
||||
state: ResourceState::new_ok(data),
|
||||
state: ResourceState::new_ok(resource_uuid, data),
|
||||
old_format_path: None,
|
||||
})))
|
||||
}
|
||||
|
||||
/// Creates new untyped resource in error state.
|
||||
pub fn new_load_error(
|
||||
resource_uuid: Uuid,
|
||||
kind: ResourceKind,
|
||||
error: LoadError,
|
||||
type_uuid: Uuid,
|
||||
) -> Self {
|
||||
pub fn new_load_error(kind: ResourceKind, error: LoadError) -> Self {
|
||||
Self(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid,
|
||||
kind,
|
||||
type_uuid,
|
||||
state: ResourceState::new_load_error(Default::default(), error),
|
||||
old_format_path: None,
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn resource_uuid(&self) -> Uuid {
|
||||
self.0.lock().resource_uuid
|
||||
pub fn resource_uuid(&self) -> Option<Uuid> {
|
||||
let header = self.0.lock();
|
||||
match header.state {
|
||||
ResourceState::Ok { resource_uuid, .. } => Some(resource_uuid),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns actual unique type id of underlying resource data.
|
||||
pub fn type_uuid(&self) -> Uuid {
|
||||
self.0.lock().type_uuid
|
||||
pub fn type_uuid(&self) -> Option<Uuid> {
|
||||
let header = self.0.lock();
|
||||
match header.state {
|
||||
ResourceState::Ok { ref data, .. } => Some(data.type_uuid()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the resource is still loading.
|
||||
@@ -439,7 +426,7 @@ impl UntypedResource {
|
||||
|
||||
/// Returns path of the untyped resource.
|
||||
pub fn kind(&self) -> ResourceKind {
|
||||
self.0.lock().kind.clone()
|
||||
self.0.lock().kind
|
||||
}
|
||||
|
||||
/// Set a new path for the untyped resource.
|
||||
@@ -454,7 +441,7 @@ impl UntypedResource {
|
||||
ResourceState::Pending { .. } | ResourceState::LoadError { .. } => {
|
||||
Err("Unable to save unloaded resource!".into())
|
||||
}
|
||||
ResourceState::Ok(ref mut data) => data.save(path),
|
||||
ResourceState::Ok { ref mut data, .. } => data.save(path),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +450,7 @@ impl UntypedResource {
|
||||
where
|
||||
T: TypedResourceData,
|
||||
{
|
||||
if self.type_uuid() == <T as TypeUuidProvider>::type_uuid() {
|
||||
if self.type_uuid() == Some(<T as TypeUuidProvider>::type_uuid()) {
|
||||
Some(Resource {
|
||||
untyped: self.clone(),
|
||||
phantom: PhantomData::<T>,
|
||||
@@ -481,10 +468,9 @@ impl UntypedResource {
|
||||
}
|
||||
|
||||
/// Changes internal state to [`ResourceState::Ok`]
|
||||
pub fn commit_ok<T: ResourceData>(&self, data: T) {
|
||||
pub fn commit_ok<T: ResourceData>(&self, resource_uuid: Uuid, data: T) {
|
||||
let mut guard = self.0.lock();
|
||||
guard.type_uuid = data.type_uuid();
|
||||
guard.state.commit_ok(data);
|
||||
guard.state.commit_ok(resource_uuid, data);
|
||||
}
|
||||
|
||||
/// Changes internal state to [`ResourceState::LoadError`].
|
||||
@@ -505,7 +491,7 @@ impl Future for UntypedResource {
|
||||
Poll::Pending
|
||||
}
|
||||
ResourceState::LoadError { ref error, .. } => Poll::Ready(Err(error.clone())),
|
||||
ResourceState::Ok(_) => Poll::Ready(Ok(self.clone())),
|
||||
ResourceState::Ok { .. } => Poll::Ready(Ok(self.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,11 +555,7 @@ mod test {
|
||||
#[test]
|
||||
fn untyped_resource_try_cast() {
|
||||
let r = UntypedResource::default();
|
||||
let r2 = UntypedResource::new_pending(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::External,
|
||||
Uuid::from_u128(0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128),
|
||||
);
|
||||
let r2 = UntypedResource::new_pending(ResourceKind::External);
|
||||
|
||||
assert!(r.try_cast::<Stub>().is_some());
|
||||
assert!(r2.try_cast::<Stub>().is_none());
|
||||
@@ -587,18 +569,17 @@ mod test {
|
||||
let mut cx = task::Context::from_waker(&waker);
|
||||
|
||||
let mut r = UntypedResource(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid: Default::default(),
|
||||
kind: ResourceKind::External,
|
||||
type_uuid: Uuid::default(),
|
||||
state: ResourceState::Ok(Box::new(stub)),
|
||||
state: ResourceState::Ok {
|
||||
data: Box::new(stub),
|
||||
resource_uuid: Uuid::new_v4(),
|
||||
},
|
||||
old_format_path: None,
|
||||
})));
|
||||
assert!(Pin::new(&mut r).poll(&mut cx).is_ready());
|
||||
|
||||
let mut r = UntypedResource(Arc::new(Mutex::new(ResourceHeader {
|
||||
resource_uuid: Default::default(),
|
||||
kind: ResourceKind::External,
|
||||
type_uuid: Uuid::default(),
|
||||
state: ResourceState::LoadError {
|
||||
path: Default::default(),
|
||||
error: Default::default(),
|
||||
|
||||
@@ -790,7 +790,7 @@ impl TextureResourceExtension for TextureResource {
|
||||
}
|
||||
|
||||
fn deep_clone(&self) -> Self {
|
||||
let kind = self.header().kind.clone();
|
||||
let kind = self.header().kind;
|
||||
let data = self.data_ref().clone();
|
||||
Resource::new_ok(Uuid::new_v4(), kind, data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user