mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Serializing resource handles
This commit is contained in:
@@ -39,6 +39,7 @@ use crate::{
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
pub use fyrox_core as core;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
any::Any,
|
||||
error::Error,
|
||||
@@ -197,7 +198,12 @@ where
|
||||
/// ## Default State
|
||||
///
|
||||
/// Default state of the resource will be [`ResourceState::Ok`] with `T::default`.
|
||||
#[derive(Reflect)]
|
||||
#[derive(Reflect, Serialize, Deserialize)]
|
||||
#[serde(
|
||||
bound = "T: TypedResourceData",
|
||||
from = "UntypedResource",
|
||||
into = "UntypedResource"
|
||||
)]
|
||||
pub struct Resource<T: Debug> {
|
||||
untyped: UntypedResource,
|
||||
#[reflect(hidden)]
|
||||
@@ -448,10 +454,12 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn from(untyped: UntypedResource) -> Self {
|
||||
assert_eq!(
|
||||
untyped.type_uuid(),
|
||||
Some(<T as TypeUuidProvider>::type_uuid())
|
||||
);
|
||||
if let Some(type_uuid) = untyped.type_uuid() {
|
||||
let expected = <T as TypeUuidProvider>::type_uuid();
|
||||
if type_uuid != expected {
|
||||
panic!("Resource type mismatch. Expected: {expected}. Found: {type_uuid}");
|
||||
}
|
||||
}
|
||||
Self {
|
||||
untyped,
|
||||
phantom: Default::default(),
|
||||
@@ -834,6 +842,24 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize() {
|
||||
let uuid = uuid!("6d1aadb5-42e1-485b-910b-fa4d81b61855");
|
||||
let typed = Resource::<MyData>::from(uuid);
|
||||
let untyped = UntypedResource::from(uuid);
|
||||
let s = ron::ser::to_string(&typed).unwrap();
|
||||
assert_eq!(&ron::ser::to_string(&uuid).unwrap(), &s);
|
||||
assert_eq!(&ron::ser::to_string(&untyped).unwrap(), &s);
|
||||
let output_uuid = ron::de::from_str::<Uuid>(&s).unwrap();
|
||||
assert_eq!(output_uuid, uuid);
|
||||
let untyped = ron::de::from_str::<UntypedResource>(&s).unwrap();
|
||||
assert_eq!(untyped.resource_uuid(), uuid);
|
||||
assert_eq!(untyped.kind(), ResourceKind::External);
|
||||
let output = ron::de::from_str::<Resource<MyData>>(&s).unwrap();
|
||||
assert_eq!(output.resource_uuid(), uuid);
|
||||
assert_eq!(output.kind(), ResourceKind::External);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_registry_scan() {
|
||||
write_test_resources(TEST_FOLDER1, 0..2);
|
||||
|
||||
@@ -37,6 +37,7 @@ use fyrox_core::io::FileError;
|
||||
use fyrox_core::log::Log;
|
||||
use fyrox_core::parking_lot::MutexGuard;
|
||||
use fyrox_core::SafeLock;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Write;
|
||||
use std::{
|
||||
error::Error,
|
||||
@@ -451,10 +452,24 @@ impl Visit for ResourceHeader {
|
||||
/// that the resource is in default state. This is a trade-off to prevent wrapping internals into
|
||||
/// `Option`, that in some cases could lead to convoluted code with lots of `unwrap`s and state
|
||||
/// assumptions.
|
||||
#[derive(Default, Clone, Reflect, TypeUuidProvider)]
|
||||
#[derive(Default, Clone, Reflect, TypeUuidProvider, Deserialize)]
|
||||
#[serde(from = "Uuid")]
|
||||
#[type_uuid(id = "21613484-7145-4d1c-87d8-62fa767560ab")]
|
||||
pub struct UntypedResource(pub Arc<Mutex<ResourceHeader>>);
|
||||
|
||||
impl Serialize for UntypedResource {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let header = self.lock();
|
||||
if header.kind == ResourceKind::Embedded {
|
||||
panic!("Embedded resources cannot be serialized.");
|
||||
}
|
||||
header.uuid.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for UntypedResource {
|
||||
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
|
||||
let result = self.visit_with_type_uuid(name, None, visitor);
|
||||
|
||||
Reference in New Issue
Block a user