Skip to content

Commit

Permalink
Asset management upgrade.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Apr 3, 2024
1 parent e575cb3 commit 58f36b4
Show file tree
Hide file tree
Showing 24 changed files with 43 additions and 161 deletions.
3 changes: 0 additions & 3 deletions assets/Box.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/Bricks.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/GreenSolid.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/PBR.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/RedSolid.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/Solid.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/Sphere.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/Suzanne.json

This file was deleted.

3 changes: 0 additions & 3 deletions assets/WhiteSolid.json

This file was deleted.

2 changes: 1 addition & 1 deletion assets/green_solid.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"parent": "Solid.json",
"parent": "solid.json",
"variables": [
{
"name": "color",
Expand Down
2 changes: 1 addition & 1 deletion assets/pbr.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{
"name": "color",
"data_type": "Texture2D",
"value": "Bricks"
"value": "patterned_brick_floor_02_diff_2k.png"
}
]
}
2 changes: 1 addition & 1 deletion assets/red_solid.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"parent": "Solid.json",
"parent": "solid.json",
"variables": [
{
"name": "color",
Expand Down
2 changes: 1 addition & 1 deletion assets/white_solid.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"parent": "Solid.json",
"parent": "solid.json",
"variables": [
{
"name": "color",
Expand Down
2 changes: 1 addition & 1 deletion resource_management/src/asset/asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ pub trait AssetHandler {
/// # Returns
/// Returns Some(...) if the asset was managed by this handler, None otherwise.
/// Returns Some(Ok(...)) if the asset was loaded successfully, Some(Err(...)) otherwise.
fn load<'a>(&'a self, asset_manager: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, id: &'a str, json: &'a json::JsonValue) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>>;
fn load<'a>(&'a self, asset_manager: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, url: &'a str, json: Option<&'a json::JsonValue>) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>>;
}
42 changes: 5 additions & 37 deletions resource_management/src/asset/asset_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,6 @@ impl AssetManager {

/// Load a source asset from a JSON asset description.
pub async fn load(&self, id: &str) -> Result<(), LoadMessages> {
let mut dir = smol::fs::read_dir(assets_path()).await.or_else(|_| Err(LoadMessages::IO))?;

let entry = dir.find(|e|
e.as_ref().unwrap().file_name().to_str().unwrap().contains(id) && e.as_ref().unwrap().path().extension().unwrap() == "json"
).await.ok_or(LoadMessages::NoAsset)?.or_else(|_| Err(LoadMessages::NoAsset))?;

let mut asset_resolver = smol::fs::File::open(entry.path()).await.or_else(|_| Err(LoadMessages::IO))?;

let mut json_string = String::with_capacity(1024);

asset_resolver.read_to_string(&mut json_string).await.or_else(|_| Err(LoadMessages::IO))?;

let json = json::parse(&json_string).or_else(|_| Err(LoadMessages::IO))?;

let url = json["url"].as_str().ok_or(LoadMessages::NoURL)?; // Source asset url

struct MyAssetResolver {}

impl AssetResolver for MyAssetResolver {
Expand All @@ -75,14 +59,14 @@ impl AssetManager {

let storage_backend = &self.storage_backend;

let asset_handler_loads = self.asset_handlers.iter().map(|asset_handler| asset_handler.load(self, &asset_resolver, storage_backend, id, &json));
let asset_handler_loads = self.asset_handlers.iter().map(|asset_handler| asset_handler.load(self, &asset_resolver, storage_backend, id, None));

let load_results = futures::future::join_all(asset_handler_loads).await;

let asset_handler_found = load_results.iter().any(|load_result| { load_result.is_ok() });

if !asset_handler_found {
log::warn!("No asset handler found for asset: {}", url);
log::warn!("No asset handler found for asset: {}", id);
return Err(LoadMessages::NoAssetHandler);
}

Expand All @@ -94,22 +78,6 @@ impl AssetManager {
}

pub async fn load_typed_resource<T: Resource>(&self, id: &str) -> Result<TypedResource<T>, LoadMessages> {
let mut dir = smol::fs::read_dir(assets_path()).await.or_else(|_| Err(LoadMessages::IO))?;

let entry = dir.find(|e|
e.as_ref().unwrap().file_name().to_str().unwrap().contains(id) && e.as_ref().unwrap().path().extension().unwrap() == "json"
).await.ok_or(LoadMessages::NoAsset)?.or_else(|_| Err(LoadMessages::NoAsset))?;

let mut asset_resolver = smol::fs::File::open(entry.path()).await.or_else(|_| Err(LoadMessages::IO))?;

let mut json_string = String::with_capacity(1024);

asset_resolver.read_to_string(&mut json_string).await.or_else(|_| Err(LoadMessages::IO))?;

let json = json::parse(&json_string).or_else(|_| Err(LoadMessages::IO))?;

let url = json["url"].as_str().ok_or(LoadMessages::NoURL)?; // Source asset url

struct MyAssetResolver {}

impl AssetResolver for MyAssetResolver {
Expand All @@ -124,14 +92,14 @@ impl AssetManager {

let storage_backend = &self.storage_backend;

let asset_handler_loads = self.asset_handlers.iter().map(|asset_handler| asset_handler.load(self, &asset_resolver, storage_backend, id, &json));
let asset_handler_loads = self.asset_handlers.iter().map(|asset_handler| asset_handler.load(self, &asset_resolver, storage_backend, id, None));

let load_results = futures::future::join_all(asset_handler_loads).await;

let asset_handler_found = load_results.iter().any(|load_result| { load_result.is_ok() });

if !asset_handler_found {
log::warn!("No asset handler found for asset: {}", url);
log::warn!("No asset handler found for asset: {}", id);
return Err(LoadMessages::NoAssetHandler);
}

Expand Down Expand Up @@ -181,7 +149,7 @@ use super::*;
}

impl AssetHandler for TestAssetHandler {
fn load<'a>(&'a self, _: &'a AssetManager, _: &'a dyn AssetResolver, _ : &'a dyn StorageBackend, id: &'a str, _: &'a json::JsonValue) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
fn load<'a>(&'a self, _: &'a AssetManager, _: &'a dyn AssetResolver, _ : &'a dyn StorageBackend, id: &'a str, _: Option<&'a json::JsonValue>) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
let res = if id == "example" {
Ok(Some(GenericResourceSerialization::new_with_serialized("id", "TestAsset", bson::Bson::Null)))
} else {
Expand Down
15 changes: 6 additions & 9 deletions resource_management/src/asset/audio_asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ impl AudioAssetHandler {
}

impl AssetHandler for AudioAssetHandler {
fn load<'a>(&'a self, _: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, id: &'a str, json: &'a json::JsonValue) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
fn load<'a>(&'a self, _: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, url: &'a str, json: Option<&'a json::JsonValue>) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
Box::pin(async move {
let url = json["url"].as_str().ok_or("No url provided".to_string())?;

if let Some(dt) = asset_resolver.get_type(url) {
if dt != "wav" { return Err("Not my type".to_string()); }
}
Expand Down Expand Up @@ -96,9 +94,11 @@ impl AssetHandler for AudioAssetHandler {
sample_count,
};

storage_backend.store(GenericResourceSerialization::new(id, audio_resource), data.into()).await.map_err(|_| format!("Failed to store resource"))?;
let resource = GenericResourceSerialization::new(url, audio_resource);

storage_backend.store(resource.clone(), data.into()).await.map_err(|_| format!("Failed to store resource"))?;

Ok(None)
Ok(Some(resource))
})
}
}
Expand All @@ -115,14 +115,11 @@ mod tests {
let audio_asset_handler = AudioAssetHandler::new();

let url = "gun.wav";
let doc = json::object! {
"url": url,
};

let asset_resolver = TestAssetResolver::new();
let storage_backend = TestStorageBackend::new();

smol::block_on(audio_asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, url, &doc)).expect("Audio asset handler did not handle asset").expect("Audio asset handler failed to load asset");
smol::block_on(audio_asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, url, None)).unwrap().expect("Audio asset handler failed to load asset");

let generated_resources = storage_backend.get_resources();

Expand Down
15 changes: 5 additions & 10 deletions resource_management/src/asset/image_asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ impl ImageAssetHandler {
}

impl AssetHandler for ImageAssetHandler {
fn load<'a>(&'a self, _: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, id: &'a str, json: &'a json::JsonValue) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
fn load<'a>(&'a self, _: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, url: &'a str, json: Option<&'a json::JsonValue>) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
Box::pin(async move {
let url = json["url"].as_str().ok_or("No url provided".to_string())?;

if let Some(dt) = asset_resolver.get_type(url) {
if dt != "png" { return Err("Not my type".to_string()); }
}
Expand Down Expand Up @@ -109,15 +107,15 @@ impl AssetHandler for ImageAssetHandler {
}
};

let resource_document = GenericResourceSerialization::new(id, Image {
let resource_document = GenericResourceSerialization::new(url, Image {
format,
extent: extent.as_array(),
compression,
});

storage_backend.store(resource_document, &data).await;
storage_backend.store(resource_document.clone(), &data).await;

Ok(None)
Ok(Some(resource_document))
})
}
}
Expand All @@ -135,11 +133,8 @@ mod tests {
let asset_handler = ImageAssetHandler::new();

let url = "patterned_brick_floor_02_diff_2k.png";
let doc = json::object! {
"url": url,
};

let result = smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, &url, &doc)).expect("Image asset handler did not handle asset");
let _ = smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, &url, None)).unwrap().expect("Image asset handler did not handle asset");

let generated_resources = storage_backend.get_resources();

Expand Down
39 changes: 11 additions & 28 deletions resource_management/src/asset/material_asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ impl MaterialAssetHandler {
}

impl AssetHandler for MaterialAssetHandler {
fn load<'a>(&'a self, asset_manager: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, id: &'a str, json: &'a json::JsonValue) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
fn load<'a>(&'a self, asset_manager: &'a AssetManager, asset_resolver: &'a dyn AssetResolver, storage_backend: &'a dyn StorageBackend, url: &'a str, json: Option<&'a json::JsonValue>) -> utils::BoxedFuture<'a, Result<Option<GenericResourceSerialization>, String>> {
Box::pin(async move {
let url = json["url"].as_str().ok_or("No url provided".to_string())?;

if let Some(dt) = asset_resolver.get_type(url) {
if dt != "json" { return Err("Not my type".to_string()); }
}
Expand Down Expand Up @@ -73,7 +71,7 @@ impl AssetHandler for MaterialAssetHandler {
}
}).collect::<Vec<_>>();

let resource = GenericResourceSerialization::new(id, Material {
let resource = GenericResourceSerialization::new(url, Material {
double_sided: false,
alpha_mode: AlphaMode::Opaque,
model: Model {
Expand All @@ -94,7 +92,7 @@ impl AssetHandler for MaterialAssetHandler {

let m_json = json::parse(&String::from_utf8_lossy(&asset_resolver.resolve(parent_material_url).await.ok_or("Failed to resolve parent material".to_string())?.0)).or_else(|_| { Err("Failed to parse JSON") })?;

let material = match self.load(asset_manager, asset_resolver, storage_backend, parent_material_url, &m_json).await {
let material = match self.load(asset_manager, asset_resolver, storage_backend, parent_material_url, None).await {
Ok(Some(m)) => { m }
Ok(None) | Err(_) => {
log::error!("Failed to load parent material");
Expand All @@ -104,7 +102,7 @@ impl AssetHandler for MaterialAssetHandler {

let material: TypedResourceModel<MaterialModel> = material.try_into().or_else(|_| { Err("Failed to convert material") })?;

let resource = GenericResourceSerialization::new(id, Variant {
let resource = GenericResourceSerialization::new(url, Variant {
material: material.solve(storage_backend).map_err(|_| { "Failed to solve material".to_string() })?,
variables: variant_json["variables"].members().map(|v| {
VariantVariable {
Expand All @@ -117,7 +115,7 @@ impl AssetHandler for MaterialAssetHandler {
match storage_backend.store(resource.clone(), &[]).await {
Ok(_) => {}
Err(_) => {
log::error!("Failed to store resource {}", id);
log::error!("Failed to store resource {}", url);
}
}

Expand Down Expand Up @@ -361,11 +359,7 @@ pub mod tests {

asset_resolver.add_file("fragment.besl", shader_file.as_bytes());

let doc = json::object! {
"url": "material.json",
};

smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, "Material.json", &doc)).expect("Image asset handler did not handle asset").expect("Failed to load material");
smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, "material.json", None)).unwrap().expect("Failed to load material");

let generated_resources = storage_backend.get_resources();

Expand All @@ -384,7 +378,7 @@ pub mod tests {

let material = &generated_resources[1];

assert_eq!(material.id, "Material.json");
assert_eq!(material.id, "material.json");
assert_eq!(material.class, "Material");
}

Expand All @@ -399,12 +393,6 @@ pub mod tests {

asset_handler.set_shader_generator(shader_generator);

let material_asset_json = r#"{
"url": "material.json"
}"#;

asset_resolver.add_file("Material.json", material_asset_json.as_bytes());

let material_json = r#"{
"domain": "World",
"type": "Surface",
Expand All @@ -430,7 +418,7 @@ pub mod tests {
asset_resolver.add_file("fragment.besl", shader_file.as_bytes());

let variant_json = r#"{
"parent": "Material.json",
"parent": "material.json",
"variables": [
{
"name": "color",
Expand All @@ -441,11 +429,7 @@ pub mod tests {

asset_resolver.add_file("variant.json", variant_json.as_bytes());

let doc = json::object! {
"url": "variant.json",
};

smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, "Variant.json", &doc)).expect("Material asset handler did not handle asset").expect("Failed to load material");
smol::block_on(asset_handler.load(&asset_manager, &asset_resolver, &storage_backend, "variant.json", None)).unwrap().expect("Failed to load material");

let generated_resources = storage_backend.get_resources();

Expand All @@ -464,13 +448,12 @@ pub mod tests {

let material = &generated_resources[1];

assert_eq!(material.id, "Material.json");
assert_eq!(material.id, "material.json");
assert_eq!(material.class, "Material");

let variant = &generated_resources[2];

assert_eq!(variant.id, "Variant.json");
assert_eq!(variant.id, "variant.json");
assert_eq!(variant.class, "Variant");
// assert_eq!(variant.parent, "Material");
}
}
Loading

0 comments on commit 58f36b4

Please sign in to comment.