mirror of
https://github.com/bevyengine/bevy
synced 2024-11-14 00:47:32 +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
|
/// Enable watching of the filesystem for changes, if support is available, starting from after
|
||||||
/// the point of calling this function.
|
/// the point of calling this function.
|
||||||
pub fn watch_for_changes(&self) -> Result<(), AssetServerError> {
|
pub fn watch_for_changes(&self) -> Result<(), AssetServerError> {
|
||||||
self.server.asset_io.watch_for_changes()?;
|
self.asset_io().watch_for_changes()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ impl AssetServer {
|
||||||
};
|
};
|
||||||
|
|
||||||
// load the asset bytes
|
// 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,
|
Ok(bytes) => bytes,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
set_asset_failed();
|
set_asset_failed();
|
||||||
|
@ -313,7 +313,7 @@ impl AssetServer {
|
||||||
let mut load_context = LoadContext::new(
|
let mut load_context = LoadContext::new(
|
||||||
asset_path.path(),
|
asset_path.path(),
|
||||||
&self.server.asset_ref_counter.channel,
|
&self.server.asset_ref_counter.channel,
|
||||||
&*self.server.asset_io,
|
self.asset_io(),
|
||||||
version,
|
version,
|
||||||
&self.server.task_pool,
|
&self.server.task_pool,
|
||||||
);
|
);
|
||||||
|
@ -361,8 +361,7 @@ impl AssetServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.server
|
self.asset_io()
|
||||||
.asset_io
|
|
||||||
.watch_path_for_changes(asset_path.path())
|
.watch_path_for_changes(asset_path.path())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.create_assets_in_load_context(&mut load_context);
|
self.create_assets_in_load_context(&mut load_context);
|
||||||
|
@ -403,15 +402,15 @@ impl AssetServer {
|
||||||
path: P,
|
path: P,
|
||||||
) -> Result<Vec<HandleUntyped>, AssetServerError> {
|
) -> Result<Vec<HandleUntyped>, AssetServerError> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
if !self.server.asset_io.is_directory(path) {
|
if !self.asset_io().is_dir(path) {
|
||||||
return Err(AssetServerError::AssetFolderNotADirectory(
|
return Err(AssetServerError::AssetFolderNotADirectory(
|
||||||
path.to_str().unwrap().to_string(),
|
path.to_str().unwrap().to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut handles = Vec::new();
|
let mut handles = Vec::new();
|
||||||
for child_path in self.server.asset_io.read_directory(path.as_ref())? {
|
for child_path in self.asset_io().read_directory(path.as_ref())? {
|
||||||
if self.server.asset_io.is_directory(&child_path) {
|
if self.asset_io().is_dir(&child_path) {
|
||||||
handles.extend(self.load_folder(&child_path)?);
|
handles.extend(self.load_folder(&child_path)?);
|
||||||
} else {
|
} else {
|
||||||
if self.get_path_asset_loader(&child_path).is_err() {
|
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 anyhow::Result;
|
||||||
use bevy_utils::BoxedFuture;
|
use bevy_utils::BoxedFuture;
|
||||||
use std::{
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
@ -46,7 +47,17 @@ impl AssetIo for AndroidAssetIo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_directory(&self, path: &Path) -> bool {
|
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||||
self.root_path.join(path).is_dir()
|
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")]
|
#[cfg(feature = "filesystem_watcher")]
|
||||||
use crate::{filesystem_watcher::FilesystemWatcher, AssetServer};
|
use crate::{filesystem_watcher::FilesystemWatcher, AssetServer};
|
||||||
use crate::{AssetIo, AssetIoError};
|
use crate::{AssetIo, AssetIoError, Metadata};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
#[cfg(feature = "filesystem_watcher")]
|
#[cfg(feature = "filesystem_watcher")]
|
||||||
use bevy_ecs::system::Res;
|
use bevy_ecs::system::Res;
|
||||||
|
@ -15,6 +15,7 @@ use parking_lot::RwLock;
|
||||||
#[cfg(feature = "filesystem_watcher")]
|
#[cfg(feature = "filesystem_watcher")]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
env, fs,
|
env, fs,
|
||||||
io::Read,
|
io::Read,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -128,8 +129,18 @@ impl AssetIo for FileAssetIo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_directory(&self, path: &Path) -> bool {
|
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||||
self.root_path.join(path).is_dir()
|
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")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
mod wasm_asset_io;
|
mod wasm_asset_io;
|
||||||
|
|
||||||
|
mod metadata;
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub use android_asset_io::*;
|
pub use android_asset_io::*;
|
||||||
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
|
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
|
||||||
|
@ -12,6 +14,8 @@ pub use file_asset_io::*;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub use wasm_asset_io::*;
|
pub use wasm_asset_io::*;
|
||||||
|
|
||||||
|
pub use metadata::*;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bevy_utils::BoxedFuture;
|
use bevy_utils::BoxedFuture;
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
|
@ -39,9 +43,23 @@ pub trait AssetIo: Downcast + Send + Sync + 'static {
|
||||||
&self,
|
&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Result<Box<dyn Iterator<Item = PathBuf>>, AssetIoError>;
|
) -> 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_path_for_changes(&self, path: &Path) -> Result<(), AssetIoError>;
|
||||||
fn watch_for_changes(&self) -> 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);
|
impl_downcast!(AssetIo);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use crate::{AssetIo, AssetIoError};
|
use crate::{AssetIo, AssetIoError, Metadata};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bevy_utils::BoxedFuture;
|
use bevy_utils::BoxedFuture;
|
||||||
use js_sys::Uint8Array;
|
use js_sys::Uint8Array;
|
||||||
use std::path::{Path, PathBuf};
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::Response;
|
use web_sys::Response;
|
||||||
|
@ -50,7 +53,17 @@ impl AssetIo for WasmAssetIo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_directory(&self, path: &Path) -> bool {
|
fn get_metadata(&self, path: &Path) -> Result<Metadata, AssetIoError> {
|
||||||
self.root_path.join(path).is_dir()
|
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 {
|
pub fn task_pool(&self) -> &TaskPool {
|
||||||
self.task_pool
|
self.task_pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn asset_io(&self) -> &dyn AssetIo {
|
||||||
|
self.asset_io
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of loading an asset of type `T`
|
/// The result of loading an asset of type `T`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
asset::{AssetIo, AssetIoError},
|
asset::{AssetIo, AssetIoError, Metadata},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
utils::BoxedFuture,
|
utils::BoxedFuture,
|
||||||
};
|
};
|
||||||
|
@ -26,11 +26,6 @@ impl AssetIo for CustomAssetIo {
|
||||||
self.0.read_directory(path)
|
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> {
|
fn watch_path_for_changes(&self, path: &Path) -> Result<(), AssetIoError> {
|
||||||
info!("watch_path_for_changes({:?})", path);
|
info!("watch_path_for_changes({:?})", path);
|
||||||
self.0.watch_path_for_changes(path)
|
self.0.watch_path_for_changes(path)
|
||||||
|
@ -40,6 +35,11 @@ impl AssetIo for CustomAssetIo {
|
||||||
info!("watch_for_changes()");
|
info!("watch_for_changes()");
|
||||||
self.0.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
|
/// A plugin used to execute the override of the asset io
|
||||||
|
|
Loading…
Reference in a new issue