#![warn(missing_docs)]
#![doc = include_str!("../readme.md")]
use std::path::PathBuf;
use bevy::{
asset::{
AssetPath,
io::{AssetSourceId, file::FileAssetReader},
},
prelude::*,
};
pub mod prelude {
pub use super::{FullAssetPathPlugin, FullAssetPathProvider};
}
#[derive(Default)]
#[non_exhaustive]
pub struct FullAssetPathPlugin;
impl Plugin for FullAssetPathPlugin {
fn build(&self, app: &mut App) {
app.register_type::<FullAssetPathProvider>();
#[cfg(target_arch = "wasm32")]
{
return;
}
let asset_plugin = get_asset_plugin(app);
let path_str = asset_plugin.file_path.clone();
let path = PathBuf::from(path_str);
app.insert_resource(FullAssetPathProvider {
relative_assets_dir: path,
});
}
}
fn get_asset_plugin(app: &App) -> &AssetPlugin {
let asset_plugins: Vec<&AssetPlugin> = app.get_added_plugins();
asset_plugins.into_iter().next().expect(ASSET_ERROR)
}
const ASSET_ERROR: &str = "bevy_full_asset_path requires access to the Bevy asset plugin. \
Please add `FullAssetPathPlugin` after `AssetPlugin`, which is commonly added as part of the `DefaultPlugins`";
#[derive(Debug, Clone, PartialEq, Eq, Hash, Resource, Deref, DerefMut, Reflect)]
#[reflect(Resource)]
pub struct FullAssetPathProvider {
relative_assets_dir: PathBuf,
}
impl FullAssetPathProvider {
pub fn full_asset_path(&self, asset_path: &AssetPath) -> Result<PathBuf, FullAssetPathError> {
match asset_path.source() {
AssetSourceId::Default => {}
AssetSourceId::Name(name) => {
return Err(FullAssetPathError::NonDefaultSource(name.to_string()));
}
};
let base_path = FileAssetReader::get_base_path();
let relative_asset_path = self.relative_assets_dir.as_path();
let full_path = base_path.join(relative_asset_path).join(asset_path.path());
Ok(full_path)
}
}
#[derive(Debug, thiserror::Error)]
pub enum FullAssetPathError {
#[error("Asset path is not coming from the default source: {0}")]
NonDefaultSource(String),
}