Added directory walking and resource is_dir and is_file checking for fbx material search

This commit is contained in:
Jacobtread
2023-10-27 16:03:17 +13:00
parent 49f9f19095
commit 8d23770050
4 changed files with 102 additions and 11 deletions
+38
View File
@@ -112,3 +112,41 @@ pub async fn exists<P: AsRef<Path>>(path: P) -> bool {
}
}
}
pub async fn is_dir<P: AsRef<Path>>(path: P) -> bool {
#[cfg(all(not(target_os = "android"), not(target_arch = "wasm32")))]
{
path.as_ref().is_dir()
}
#[cfg(target_os = "android")]
{
ANDROID_APP
.get()
.map(|v| {
v.asset_manager()
.open_dir(&std::ffi::CString::new(path.as_ref().to_str().unwrap()).unwrap())
.is_some()
})
.unwrap_or_default()
}
// TODO: Is directory checking possible on wasm?
#[cfg(target_arch = "wasm32")]
{
false
}
}
pub async fn is_file<P: AsRef<Path>>(path: P) -> bool {
#[cfg(all(not(target_os = "android"), not(target_arch = "wasm32")))]
{
path.as_ref().is_file()
}
// On android of wasm the default exists logic works for files
#[cfg(any(target_os = "android", target_arch = "wasm32"))]
{
exists(path).await
}
}
+1
View File
@@ -19,3 +19,4 @@ fyrox-core = { path = "../fyrox-core", version = "0.26.0" }
fxhash = "0.2.1"
ron = "0.8.0"
serde = { version = "1", features = ["derive"] }
walkdir = "2.3.2"
+47 -2
View File
@@ -3,11 +3,13 @@
use std::{
fmt::Debug,
future::ready,
io::{Cursor, Read, Seek},
path::Path,
path::{Path, PathBuf},
};
use fyrox_core::{futures::future::BoxFuture, io::FileLoadError};
use walkdir::WalkDir;
/// Trait for files readers ensuring they implement the required traits
pub trait FileReader: Debug + Send + Read + Seek + 'static {}
@@ -21,6 +23,13 @@ pub trait ResourceIo: Send + Sync + 'static {
/// the entire byte contents of the file or an error
fn load_file<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, Result<Vec<u8>, FileLoadError>>;
/// Provides an iterator over the paths present in the provided
/// path directory FsResourceIo uses WalkDir bu
fn walk_directory<'a>(
&'a self,
path: &'a Path,
) -> BoxFuture<'a, Result<Box<dyn Iterator<Item = PathBuf>>, FileLoadError>>;
/// Attempts to open a file reader to the proivded path for
/// reading its bytes
///
@@ -39,6 +48,12 @@ pub trait ResourceIo: Send + Sync + 'static {
/// Used to check whether a path exists
fn exists<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool>;
/// Used to check whether a path is a file
fn is_file<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool>;
/// Used to check whether a path is a dir
fn is_dir<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool>;
}
/// Standard resource IO provider that uses the file system to
@@ -51,7 +66,29 @@ impl ResourceIo for FsResourceIo {
Box::pin(fyrox_core::io::load_file(path))
}
// Only use file reader when not targetting android or wasm
fn walk_directory<'a>(
&'a self,
path: &'a Path,
) -> BoxFuture<'a, Result<Box<dyn Iterator<Item = PathBuf>>, FileLoadError>> {
Box::pin(async move {
// TODO: I'm not sure if WalkDir is acceptable for wasm and mobile platforms
// might need to be updated for those platforms
let iter = WalkDir::new(path)
.into_iter()
.flatten()
.map(|value| value.into_path());
let iter: Box<dyn Iterator<Item = PathBuf>> = Box::new(iter);
Ok(iter)
})
}
/// Only use file reader when not targetting android or wasm
///
/// Note: Might be possible to using the android Asset for reading as
/// long as its Send + Sync + 'static (It already implements Debug + Read + Seek)
#[cfg(all(not(target_os = "android"), not(target_arch = "wasm32")))]
fn file_reader<'a>(
&'a self,
@@ -71,4 +108,12 @@ impl ResourceIo for FsResourceIo {
fn exists<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool> {
Box::pin(fyrox_core::io::exists(path))
}
fn is_file<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool> {
Box::pin(fyrox_core::io::is_file(path))
}
fn is_dir<'a>(&'a self, path: &'a Path) -> BoxFuture<'a, bool> {
Box::pin(fyrox_core::io::is_dir(path))
}
}
+16 -9
View File
@@ -17,7 +17,6 @@ use crate::{
algebra::{Matrix4, Point3, UnitQuaternion, Vector2, Vector3, Vector4},
curve::{CurveKey, CurveKeyKind},
instant::Instant,
io,
log::{Log, MessageKind},
math::{self, triangulator::triangulate, RotationOrder},
pool::Handle,
@@ -67,7 +66,6 @@ use std::{
hash::{Hash, Hasher},
path::Path,
};
use walkdir::WalkDir;
/// Input angles in degrees
fn quat_from_euler(euler: Vector3<f32>) -> UnitQuaternion<f32> {
@@ -308,6 +306,9 @@ async fn create_surfaces(
),
)
}
let io = resource_manager.resource_io();
for (name, texture_handle) in material.textures.iter() {
let texture = fbx_scene.get(*texture_handle).as_texture()?;
let path = texture.get_file_path();
@@ -322,7 +323,7 @@ async fn create_surfaces(
let mut path = model_path.to_owned();
while let Some(parent) = path.parent() {
let candidate = parent.join(filename);
if io::exists(&candidate).await {
if io.exists(&candidate).await {
texture_path = Some(candidate);
break;
}
@@ -332,15 +333,21 @@ async fn create_surfaces(
}
MaterialSearchOptions::WorkingDirectory => {
let mut texture_path = None;
for dir in WalkDir::new(".").into_iter().flatten() {
if dir.path().is_dir() {
let candidate = dir.path().join(filename);
if candidate.exists() {
texture_path = Some(candidate);
break;
let path = Path::new(".");
if let Ok(iter) = io.walk_directory(path).await {
for dir in iter {
if io.is_dir(&dir).await {
let candidate = dir.join(filename);
if candidate.exists() {
texture_path = Some(candidate);
break;
}
}
}
}
texture_path
}
MaterialSearchOptions::UsePathDirectly => Some(path.clone()),