ability to create metadata files + fixed all tests

This commit is contained in:
Dmitry Stepanov
2025-04-05 11:17:15 +03:00
parent aa9b407004
commit 202ed9a7b3
12 changed files with 86 additions and 41 deletions
+2
View File
@@ -12,6 +12,8 @@
/fyrox-resource/test.txt
/fyrox-core-derive/test_output
/fyrox-resource/test_output
/fyrox-resource/test_output1
/fyrox-resource/test_output2
/fyrox-impl/test_output
history.bin
settings.ron
+1 -1
View File
@@ -304,7 +304,7 @@ impl RenderDataBundleStorageTrait for BatchContainer {
/// fn create_cube_mesh(graph: &mut Graph) -> Handle<Node> {
/// let cube_surface_data = SurfaceData::make_cube(Matrix4::identity());
///
/// let cube_surface = SurfaceBuilder::new(SurfaceResource::new_ok(ResourceKind::Embedded, cube_surface_data)).build();
/// let cube_surface = SurfaceBuilder::new(SurfaceResource::new_embedded(cube_surface_data)).build();
///
/// MeshBuilder::new(BaseBuilder::new())
/// .with_surfaces(vec![cube_surface])
+2 -2
View File
@@ -1213,7 +1213,7 @@ impl SurfaceResourceExtension for SurfaceResource {
///
/// let data = SurfaceData::new(vertex_buffer, triangle_buffer);
///
/// SurfaceBuilder::new(SurfaceResource::new_ok(ResourceKind::Embedded, data)).build()
/// SurfaceBuilder::new(SurfaceResource::new_embedded(data)).build()
/// }
/// ```
///
@@ -1230,7 +1230,7 @@ impl SurfaceResourceExtension for SurfaceResource {
/// # };
/// use fyrox_resource::untyped::ResourceKind;
/// fn create_cone_surface() -> Surface {
/// SurfaceBuilder::new(SurfaceResource::new_ok(ResourceKind::Embedded, SurfaceData::make_cone(
/// SurfaceBuilder::new(SurfaceResource::new_embedded(SurfaceData::make_cone(
/// 16,
/// 1.0,
/// 2.0,
+1 -2
View File
@@ -532,8 +532,7 @@ impl Scene {
/// let mut scene = Scene::new();
///
/// MeshBuilder::new(BaseBuilder::new())
/// .with_surfaces(vec![SurfaceBuilder::new(SurfaceResource::new_ok( ResourceKind::Embedded,
/// SurfaceData::make_cube(Default::default()),
/// .with_surfaces(vec![SurfaceBuilder::new(SurfaceResource::new_embedded(SurfaceData::make_cube(Default::default()),
/// ))
/// .build()])
/// .build(&mut scene.graph);
+14 -5
View File
@@ -718,11 +718,7 @@ mod test {
// Initialize resource manager and re-load the scene.
let resource_manager = ResourceManager::new(Arc::new(Default::default()));
engine::initialize_resource_manager_loaders(
&resource_manager,
Arc::new(SerializationContext::new()),
);
resource_manager.update_and_load_registry("test_output/resources.registry");
let serialization_context = SerializationContext::new();
serialization_context
.script_constructors
@@ -734,6 +730,13 @@ mod test {
.iter()
.any(|s| s.1.source_path == file!()));
engine::initialize_resource_manager_loaders(
&resource_manager,
Arc::new(serialization_context),
);
resource_manager.update_and_load_registry("test_output/resources.registry");
let root_asset = block_on(resource_manager.request::<Model>(root_asset_path)).unwrap();
// Create root resource instance in a derived resource.
@@ -760,6 +763,12 @@ mod test {
assert!(!mesh.surfaces()[0].material.is_modified());
mesh.set_cast_shadows(false);
save_scene(&mut derived, derived_asset_path);
resource_manager
.state()
.resource_registry
.lock()
.write_metadata(Uuid::new_v4(), derived_asset_path.to_path_buf())
.unwrap();
}
// Reload the derived asset and check its content.
+1 -1
View File
@@ -217,7 +217,7 @@ impl Visit for ParticleSystemRng {
/// )
/// .with_radius(0.01)
/// .build()])
/// .with_material(MaterialResource::new_ok(Default::default(), material))
/// .with_material(MaterialResource::new_embedded(material))
/// .build(graph);
/// }
/// ```
+1 -1
View File
@@ -147,7 +147,7 @@ impl VertexTrait for SpriteVertex {
/// .bind("smoke.png", resource_manager.request::<Texture>("smoke.png"));
///
/// SpriteBuilder::new(BaseBuilder::new())
/// .with_material(MaterialResource::new_ok(Default::default(), material))
/// .with_material(MaterialResource::new_embedded(material))
/// .build(graph)
/// }
/// ```
+26 -18
View File
@@ -760,37 +760,40 @@ mod tests {
}
}
const TEST_FOLDER: &'static str = "./test_output";
const TEST_FOLDER1: &'static str = "./test_output1";
const TEST_FOLDER2: &'static str = "./test_output2";
fn make_file_path(n: usize) -> PathBuf {
Path::new(TEST_FOLDER).join(format!("test{n}.{}", MyDataLoader::EXT))
fn make_file_path(root: &str, n: usize) -> PathBuf {
Path::new(root).join(format!("test{n}.{}", MyDataLoader::EXT))
}
fn make_metadata_file_path(n: usize) -> PathBuf {
Path::new(TEST_FOLDER).join(format!(
fn make_metadata_file_path(root: &str, n: usize) -> PathBuf {
Path::new(root).join(format!(
"test{n}.{}.{}",
MyDataLoader::EXT,
ResourceMetadata::EXTENSION
))
}
fn write_test_resources(indices: Range<usize>) {
let path = Path::new(TEST_FOLDER);
fn write_test_resources(root: &str, indices: Range<usize>) {
let path = Path::new(root);
if !std::fs::exists(path).unwrap() {
std::fs::create_dir_all(path).unwrap();
}
for i in indices {
MyData { data: i as u32 }.save(&make_file_path(i)).unwrap();
MyData { data: i as u32 }
.save(&make_file_path(root, i))
.unwrap();
}
}
#[test]
fn test_registry_scan() {
write_test_resources(0..2);
write_test_resources(TEST_FOLDER1, 0..2);
assert!(std::fs::exists(make_file_path(0)).unwrap());
assert!(std::fs::exists(make_file_path(1)).unwrap());
assert!(std::fs::exists(make_file_path(TEST_FOLDER1, 0)).unwrap());
assert!(std::fs::exists(make_file_path(TEST_FOLDER1, 1)).unwrap());
let io = Arc::new(FsResourceIo);
@@ -798,22 +801,27 @@ mod tests {
loaders.set(MyDataLoader {});
let loaders = Arc::new(Mutex::new(loaders));
let registry = block_on(ResourceRegistry::scan(io, loaders, TEST_FOLDER));
let registry = block_on(ResourceRegistry::scan(
io,
loaders,
Path::new(TEST_FOLDER1).join("resources.registry"),
));
assert!(std::fs::exists(make_metadata_file_path(0)).unwrap());
assert!(std::fs::exists(make_metadata_file_path(1)).unwrap());
assert!(std::fs::exists(make_metadata_file_path(TEST_FOLDER1, 0)).unwrap());
assert!(std::fs::exists(make_metadata_file_path(TEST_FOLDER1, 1)).unwrap());
assert_eq!(registry.len(), 2);
}
#[test]
fn test_resource_manager_request_simple() {
write_test_resources(2..4);
write_test_resources(TEST_FOLDER2, 2..4);
let resource_manager = ResourceManager::new(Arc::new(TaskPool::new()));
resource_manager.add_loader(MyDataLoader {});
resource_manager.update_and_load_registry(ResourceRegistry::DEFAULT_PATH);
let path1 = make_file_path(2);
let path2 = make_file_path(3);
resource_manager
.update_and_load_registry(Path::new(TEST_FOLDER2).join("resources.registry"));
let path1 = make_file_path(TEST_FOLDER2, 2);
let path2 = make_file_path(TEST_FOLDER2, 3);
let res1 = resource_manager.request::<MyData>(path1);
let res2 = resource_manager.request::<MyData>(path2);
assert_eq!(block_on(res1).unwrap().data_ref().data, 2);
+21 -4
View File
@@ -22,6 +22,8 @@ use crate::io::ResourceIo;
use fyrox_core::{io::FileError, Uuid};
use ron::ser::PrettyConfig;
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::Write;
use std::path::Path;
#[derive(Serialize, Deserialize)]
@@ -38,7 +40,7 @@ impl ResourceMetadata {
}
}
pub async fn load_from_file(
pub async fn load_from_file_async(
path: &Path,
resource_io: &dyn ResourceIo,
) -> Result<Self, FileError> {
@@ -52,14 +54,29 @@ impl ResourceMetadata {
})
}
pub async fn save(&self, path: &Path, resource_io: &dyn ResourceIo) -> Result<(), FileError> {
let string = ron::ser::to_string_pretty(self, PrettyConfig::default()).map_err(|err| {
fn serialize(&self, path: &Path) -> Result<String, FileError> {
ron::ser::to_string_pretty(self, PrettyConfig::default()).map_err(|err| {
FileError::Custom(format!(
"Unable to serialize resource metadata for {} resource! Reason: {}",
path.display(),
err
))
})?;
})
}
pub async fn save_async(
&self,
path: &Path,
resource_io: &dyn ResourceIo,
) -> Result<(), FileError> {
let string = self.serialize(path)?;
resource_io.write_file(path, string.into_bytes()).await
}
pub fn save_sync(&self, path: &Path) -> Result<(), FileError> {
let string = self.serialize(path)?;
let mut file = File::create(path)?;
file.write_all(string.as_bytes())?;
Ok(())
}
}
+13 -2
View File
@@ -199,6 +199,15 @@ impl ResourceRegistry {
replace_slashes(ret)
}
pub fn write_metadata(&mut self, uuid: Uuid, path: impl AsRef<Path>) -> Result<(), FileError> {
ResourceMetadata::new_with_random_id().save_sync(&append_extension(
path.as_ref(),
ResourceMetadata::EXTENSION,
))?;
self.register(uuid, path.as_ref().to_path_buf());
Ok(())
}
pub fn register(&mut self, uuid: Uuid, path: PathBuf) -> Option<PathBuf> {
self.paths.insert(uuid, path)
}
@@ -301,7 +310,7 @@ impl ResourceRegistry {
let metadata_path = append_extension(&path, ResourceMetadata::EXTENSION);
let metadata =
match ResourceMetadata::load_from_file(&metadata_path, &*resource_io).await {
match ResourceMetadata::load_from_file_async(&metadata_path, &*resource_io).await {
Ok(metadata) => metadata,
Err(err) => {
warn!(
@@ -312,7 +321,9 @@ impl ResourceRegistry {
err
);
let new_metadata = ResourceMetadata::new_with_random_id();
if let Err(err) = new_metadata.save(&metadata_path, &*resource_io).await {
if let Err(err) =
new_metadata.save_async(&metadata_path, &*resource_io).await
{
warn!(
"Unable to save resource {} metadata. Reason: {:?}",
path.display(),
+2 -1
View File
@@ -44,6 +44,7 @@
//! use fyrox_sound::renderer::Renderer;
//! use std::path::{Path, PathBuf};
//! use hrtf::HrirSphere;
//! use fyrox_resource::untyped::ResourceKind;
//!
//! fn use_hrtf(context: &mut SoundContext) {
//! // IRC_1002_C.bin is HRIR sphere in binary format, can be any valid HRIR sphere
@@ -51,7 +52,7 @@
//! let hrir_path = PathBuf::from("examples/data/IRC_1002_C.bin");
//! let hrir_sphere = HrirSphere::from_file(&hrir_path, context::SAMPLE_RATE).unwrap();
//!
//! context.state().set_renderer(Renderer::HrtfRenderer(HrtfRenderer::new(HrirSphereResource::from_hrir_sphere(hrir_sphere, hrir_path.into()))));
//! context.state().set_renderer(Renderer::HrtfRenderer(HrtfRenderer::new(HrirSphereResource::from_hrir_sphere(hrir_sphere, ResourceKind::Embedded))));
//! }
//! ```
//!
+2 -4
View File
@@ -216,7 +216,6 @@ impl<T: Visit> Visit for StyledProperty<T> {
/// # widget::WidgetBuilder,
/// # Thickness, UserInterface,
/// # };
/// # use fyrox_resource::untyped::ResourceKind;
/// #
/// fn build_with_style(ui: &mut UserInterface) {
/// // The context will use UI style by default. You can override it using `ui.set_style(..)`.
@@ -228,7 +227,7 @@ impl<T: Visit> Visit for StyledProperty<T> {
/// .with(Button::CORNER_RADIUS, 6.0f32)
/// .with(Button::BORDER_THICKNESS, Thickness::uniform(3.0));
///
/// ctx.style = StyleResource::new_ok(ResourceKind::Embedded, style);
/// ctx.style = StyleResource::new_embedded(style);
///
/// // The button will have corner radius of 6.0 points and border thickness of 3.0 points on
/// // each side.
@@ -244,14 +243,13 @@ impl<T: Visit> Visit for StyledProperty<T> {
/// style::{resource::StyleResource, Style},
/// Thickness, UserInterface,
/// };
/// use fyrox_resource::untyped::ResourceKind;
///
/// fn apply_style(ui: &mut UserInterface) {
/// let style = Style::light_style()
/// .with(Button::CORNER_RADIUS, 3.0f32)
/// .with(Button::BORDER_THICKNESS, Thickness::uniform(1.0));
///
/// ui.set_style(StyleResource::new_ok(ResourceKind::Embedded, style));
/// ui.set_style(StyleResource::new_embedded(style));
/// }
/// ```
#[derive(Visit, Reflect, Default, Debug, TypeUuidProvider)]