mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Add file metadata to AssetIo (#2123)
This is a replacement for #2106 This adds a `Metadata` struct which contains metadata information about a file, at the moment only the file type. It also adds a `get_metadata` to `AssetIo` trait and an `asset_io` accessor method to `AssetServer` and `LoadContext` I am not sure about the changes in `AndroidAssetIo ` and `WasmAssetIo`.
This commit is contained in:
parent
8283db69b4
commit
e29bd50de8
8 changed files with 158 additions and 25 deletions
|
@ -124,7 +124,7 @@ impl AssetServer {
|
|||
/// Enable watching of the filesystem for changes, if support is available, starting from after
|
||||
/// the point of calling this function.
|
||||
pub fn watch_for_changes(&self) -> Result<(), AssetServerError> {
|
||||
self.server.asset_io.watch_for_changes()?;
|
||||
self.asset_io().watch_for_changes()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,7 @@ impl AssetServer {
|
|||
};
|
||||
|
||||
// load the asset bytes
|
||||
let bytes = match self.server.asset_io.load_path(asset_path.path()).await {
|
||||
let bytes = match self.asset_io().load_path(asset_path.path()).await {
|
||||
Ok(bytes) => bytes,
|
||||
Err(err) => {
|
||||
set_asset_failed();
|
||||
|
@ -313,7 +313,7 @@ impl AssetServer {
|
|||
let mut load_context = LoadContext::new(
|
||||
asset_path.path(),
|
||||
&self.server.asset_ref_counter.channel,
|
||||
&*self.server.asset_io,
|
||||
self.asset_io(),
|
||||
version,
|
||||
&self.server.task_pool,
|
||||
);
|
||||
|
@ -361,8 +361,7 @@ impl AssetServer {
|
|||
}
|
||||
}
|
||||
|
||||
self.server
|
||||
.asset_io
|
||||
self.asset_io()
|
||||
.watch_path_for_changes(asset_path.path())
|
||||
.unwrap();
|
||||
self.create_assets_in_load_context(&mut load_context);
|
||||
|
@ -403,15 +402,15 @@ impl AssetServer {
|
|||
path: P,
|
||||
) -> Result<Vec<HandleUntyped>, AssetServerError> {
|
||||
let path = path.as_ref();
|
||||
if !self.server.asset_io.is_directory(path) {
|
||||
if !self.asset_io().is_dir(path) {
|
||||
return Err(AssetServerError::AssetFolderNotADirectory(
|
||||
path.to_str().unwrap().to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut handles = Vec::new();
|
||||
for child_path in self.server.asset_io.read_directory(path.as_ref())? {
|
||||
if self.server.asset_io.is_directory(&child_path) {
|
||||
for child_path in self.asset_io().read_directory(path.as_ref())? {
|
||||
if self.asset_io().is_dir(&child_path) {
|
||||
handles.extend(self.load_folder(&child_path)?);
|
||||
} else {
|
||||
if self.get_path_asset_loader(&child_path).is_err() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{AssetIo, AssetIoError};
|
||||
use crate::{AssetIo, AssetIoError, Metadata};
|
||||
use anyhow::Result;
|
||||
use bevy_utils::BoxedFuture;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
ffi::CString,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
@ -46,7 +47,17 @@ impl AssetIo for AndroidAssetIo {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_directory(&self, path: &Path) -> bool {
|
||||
self.root_path.join(path).is_dir()
|
||||
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||
let full_path = self.root_path.join(path);
|
||||
full_path
|
||||
.metadata()
|
||||
.and_then(Metadata::try_from)
|
||||
.map_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
AssetIoError::NotFound(full_path)
|
||||
} else {
|
||||
e.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[cfg(feature = "filesystem_watcher")]
|
||||
use crate::{filesystem_watcher::FilesystemWatcher, AssetServer};
|
||||
use crate::{AssetIo, AssetIoError};
|
||||
use crate::{AssetIo, AssetIoError, Metadata};
|
||||
use anyhow::Result;
|
||||
#[cfg(feature = "filesystem_watcher")]
|
||||
use bevy_ecs::system::Res;
|
||||
|
@ -15,6 +15,7 @@ use parking_lot::RwLock;
|
|||
#[cfg(feature = "filesystem_watcher")]
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
env, fs,
|
||||
io::Read,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -128,8 +129,18 @@ impl AssetIo for FileAssetIo {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_directory(&self, path: &Path) -> bool {
|
||||
self.root_path.join(path).is_dir()
|
||||
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||
let full_path = self.root_path.join(path);
|
||||
full_path
|
||||
.metadata()
|
||||
.and_then(Metadata::try_from)
|
||||
.map_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
AssetIoError::NotFound(full_path)
|
||||
} else {
|
||||
e.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
77
crates/bevy_asset/src/io/metadata.rs
Normal file
77
crates/bevy_asset/src/io/metadata.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
/// A enum representing a type of file.
|
||||
#[non_exhaustive]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum FileType {
|
||||
Directory,
|
||||
File,
|
||||
}
|
||||
|
||||
impl FileType {
|
||||
#[inline]
|
||||
pub const fn is_dir(&self) -> bool {
|
||||
matches!(self, Self::Directory)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_file(&self) -> bool {
|
||||
matches!(self, Self::File)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<std::fs::FileType> for FileType {
|
||||
type Error = std::io::Error;
|
||||
|
||||
fn try_from(file_type: std::fs::FileType) -> Result<Self, Self::Error> {
|
||||
if file_type.is_dir() {
|
||||
Ok(Self::Directory)
|
||||
} else if file_type.is_file() {
|
||||
Ok(Self::File)
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"unknown file type",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata information about a file.
|
||||
///
|
||||
/// This structure is returned from the [`AssetIo::get_metadata`](crate::AssetIo) method.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Metadata {
|
||||
file_type: FileType,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
pub fn new(file_type: FileType) -> Self {
|
||||
Self { file_type }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn file_type(&self) -> FileType {
|
||||
self.file_type
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_dir(&self) -> bool {
|
||||
self.file_type.is_dir()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn is_file(&self) -> bool {
|
||||
self.file_type.is_file()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<std::fs::Metadata> for Metadata {
|
||||
type Error = std::io::Error;
|
||||
|
||||
fn try_from(metadata: std::fs::Metadata) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
file_type: metadata.file_type().try_into()?,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ mod file_asset_io;
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
mod wasm_asset_io;
|
||||
|
||||
mod metadata;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub use android_asset_io::*;
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
|
||||
|
@ -12,6 +14,8 @@ pub use file_asset_io::*;
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
pub use wasm_asset_io::*;
|
||||
|
||||
pub use metadata::*;
|
||||
|
||||
use anyhow::Result;
|
||||
use bevy_utils::BoxedFuture;
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
|
@ -39,9 +43,23 @@ pub trait AssetIo: Downcast + Send + Sync + 'static {
|
|||
&self,
|
||||
path: &Path,
|
||||
) -> Result<Box<dyn Iterator<Item = PathBuf>>, AssetIoError>;
|
||||
fn is_directory(&self, path: &Path) -> bool;
|
||||
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError>;
|
||||
fn watch_path_for_changes(&self, path: &Path) -> Result<(), AssetIoError>;
|
||||
fn watch_for_changes(&self) -> Result<(), AssetIoError>;
|
||||
|
||||
fn is_dir(&self, path: &Path) -> bool {
|
||||
self.get_metadata(path)
|
||||
.as_ref()
|
||||
.map(Metadata::is_dir)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_file(&self, path: &Path) -> bool {
|
||||
self.get_metadata(path)
|
||||
.as_ref()
|
||||
.map(Metadata::is_file)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl_downcast!(AssetIo);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use crate::{AssetIo, AssetIoError};
|
||||
use crate::{AssetIo, AssetIoError, Metadata};
|
||||
use anyhow::Result;
|
||||
use bevy_utils::BoxedFuture;
|
||||
use js_sys::Uint8Array;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::Response;
|
||||
|
@ -50,7 +53,17 @@ impl AssetIo for WasmAssetIo {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_directory(&self, path: &Path) -> bool {
|
||||
self.root_path.join(path).is_dir()
|
||||
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||
let full_path = self.root_path.join(path);
|
||||
full_path
|
||||
.metadata()
|
||||
.and_then(Metadata::try_from)
|
||||
.map_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
AssetIoError::NotFound(full_path)
|
||||
} else {
|
||||
e.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,6 +147,10 @@ impl<'a> LoadContext<'a> {
|
|||
pub fn task_pool(&self) -> &TaskPool {
|
||||
self.task_pool
|
||||
}
|
||||
|
||||
pub fn asset_io(&self) -> &dyn AssetIo {
|
||||
self.asset_io
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of loading an asset of type `T`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bevy::{
|
||||
asset::{AssetIo, AssetIoError},
|
||||
asset::{AssetIo, AssetIoError, Metadata},
|
||||
prelude::*,
|
||||
utils::BoxedFuture,
|
||||
};
|
||||
|
@ -26,11 +26,6 @@ impl AssetIo for CustomAssetIo {
|
|||
self.0.read_directory(path)
|
||||
}
|
||||
|
||||
fn is_directory(&self, path: &Path) -> bool {
|
||||
info!("is_directory({:?})", path);
|
||||
self.0.is_directory(path)
|
||||
}
|
||||
|
||||
fn watch_path_for_changes(&self, path: &Path) -> Result<(), AssetIoError> {
|
||||
info!("watch_path_for_changes({:?})", path);
|
||||
self.0.watch_path_for_changes(path)
|
||||
|
@ -40,6 +35,11 @@ impl AssetIo for CustomAssetIo {
|
|||
info!("watch_for_changes()");
|
||||
self.0.watch_for_changes()
|
||||
}
|
||||
|
||||
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||
info!("get_metadata({:?})", path);
|
||||
self.0.get_metadata(path)
|
||||
}
|
||||
}
|
||||
|
||||
/// A plugin used to execute the override of the asset io
|
||||
|
|
Loading…
Reference in a new issue