mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Added directory walking and resource is_dir and is_file checking for fbx material search
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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()),
|
||||
|
||||
Reference in New Issue
Block a user