Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/bevy_animation/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use bevy_ecs::{
system::{Res, ResMut},
};
use bevy_platform::collections::HashMap;
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
use derive_more::derive::From;
use petgraph::{
graph::{DiGraph, NodeIndex},
Expand Down Expand Up @@ -238,7 +238,7 @@ pub enum AnimationNodeType {
///
/// The canonical extension for [`AnimationGraph`]s is `.animgraph.ron`. Plain
/// `.animgraph` is supported as well.
#[derive(Default)]
#[derive(Default, TypePath)]
pub struct AnimationGraphAssetLoader;

/// Errors that can occur when serializing animation graphs to RON.
Expand Down
96 changes: 79 additions & 17 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ mod tests {
sub_texts: Vec<String>,
}

#[derive(Default)]
#[derive(Default, TypePath)]
pub struct CoolTextLoader;

#[derive(Error, Debug)]
Expand Down Expand Up @@ -1864,6 +1864,7 @@ mod tests {
.init_asset::<SubText>()
.register_asset_loader(CoolTextLoader);

#[derive(TypePath)]
struct NestedLoadOfSubassetLoader;

impl AssetLoader for NestedLoadOfSubassetLoader {
Expand Down Expand Up @@ -2301,6 +2302,7 @@ mod tests {
unused,
reason = "We only use this for asset processor tests, which are only compiled with the `multi_threaded` feature."
)]
#[derive(TypePath)]
struct CoolTextSaver;

impl AssetSaver for CoolTextSaver {
Expand Down Expand Up @@ -2342,12 +2344,13 @@ mod tests {
unused,
reason = "We only use this for asset processor tests, which are only compiled with the `multi_threaded` feature."
)]
#[derive(TypePath)]
// Note: while we allow any Fn, since closures are unnameable types, creating a processor with a
// closure cannot be used (since we need to include the name of the transformer in the meta
// file).
struct RootAssetTransformer<M: MutateAsset<A>, A: Asset>(M, PhantomData<fn(&mut A)>);

trait MutateAsset<A: Asset>: Send + Sync + 'static {
trait MutateAsset<A: Asset>: TypePath + Send + Sync + 'static {
fn mutate(&self, asset: &mut A);
}

Expand Down Expand Up @@ -2423,6 +2426,19 @@ mod tests {
assert_eq!(processed_asset, source_asset);
}

// The asset processor currently requires multi_threaded.
#[cfg(feature = "multi_threaded")]
#[derive(TypePath)]
struct AddText;

// The asset processor currently requires multi_threaded.
#[cfg(feature = "multi_threaded")]
impl MutateAsset<CoolText> for AddText {
fn mutate(&self, text: &mut CoolText) {
text.text.push_str("_def");
}
}

// The asset processor currently requires multi_threaded.
#[cfg(feature = "multi_threaded")]
#[test]
Expand All @@ -2433,14 +2449,6 @@ mod tests {
processed_dir,
} = create_app_with_asset_processor();

struct AddText;

impl MutateAsset<CoolText> for AddText {
fn mutate(&self, text: &mut CoolText) {
text.text.push_str("_def");
}
}

type CoolTextProcessor = LoadTransformAndSave<
CoolTextLoader,
RootAssetTransformer<AddText, CoolText>,
Expand Down Expand Up @@ -2493,13 +2501,67 @@ mod tests {
processed_dir,
} = create_app_with_asset_processor();

struct AddText;
type CoolTextProcessor = LoadTransformAndSave<
CoolTextLoader,
RootAssetTransformer<AddText, CoolText>,
CoolTextSaver,
>;
app.register_asset_loader(CoolTextLoader)
.register_asset_processor(CoolTextProcessor::new(
RootAssetTransformer::new(AddText),
CoolTextSaver,
));

impl MutateAsset<CoolText> for AddText {
fn mutate(&self, text: &mut CoolText) {
text.text.push_str("_def");
}
}
let path = Path::new("abc.cool.ron");
source_dir.insert_asset_text(
path,
r#"(
text: "abc",
dependencies: [],
embedded_dependencies: [],
sub_texts: [],
)"#,
);
source_dir.insert_meta_text(path, r#"(
meta_format_version: "1.0",
asset: Process(
processor: "bevy_asset::processor::process::LoadTransformAndSave<bevy_asset::tests::CoolTextLoader, bevy_asset::tests::RootAssetTransformer<bevy_asset::tests::AddText, bevy_asset::tests::CoolText>, bevy_asset::tests::CoolTextSaver>",
settings: (
loader_settings: (),
transformer_settings: (),
saver_settings: (),
),
),
)"#);

// Start the app, which also starts the asset processor.
app.update();

// Wait for all processing to finish.
bevy_tasks::block_on(
app.world()
.resource::<AssetProcessor>()
.data()
.wait_until_finished(),
);

let processed_asset = processed_dir.get_asset(path).unwrap();
let processed_asset = str::from_utf8(processed_asset.value()).unwrap();
assert_eq!(
processed_asset,
r#"(text:"abc_def",dependencies:[],embedded_dependencies:[],sub_texts:[])"#
);
}

// The asset processor currently requires multi_threaded.
#[cfg(feature = "multi_threaded")]
#[test]
fn asset_processor_transforms_asset_with_short_path_meta() {
let AppWithProcessor {
mut app,
source_dir,
processed_dir,
} = create_app_with_asset_processor();

type CoolTextProcessor = LoadTransformAndSave<
CoolTextLoader,
Expand All @@ -2525,7 +2587,7 @@ mod tests {
source_dir.insert_meta_text(path, r#"(
meta_format_version: "1.0",
asset: Process(
processor: "bevy_asset::processor::process::LoadTransformAndSave<bevy_asset::tests::CoolTextLoader, bevy_asset::tests::RootAssetTransformer<bevy_asset::tests::asset_processor_transforms_asset_with_meta::AddText, bevy_asset::tests::CoolText>, bevy_asset::tests::CoolTextSaver>",
processor: "LoadTransformAndSave<CoolTextLoader, RootAssetTransformer<AddText, CoolText>, CoolTextSaver>",
settings: (
loader_settings: (),
transformer_settings: (),
Expand Down
13 changes: 7 additions & 6 deletions crates/bevy_asset/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use alloc::{
use atomicow::CowArc;
use bevy_ecs::{error::BevyError, world::World};
use bevy_platform::collections::{HashMap, HashSet};
use bevy_reflect::TypePath;
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
use core::any::{Any, TypeId};
use downcast_rs::{impl_downcast, Downcast};
Expand All @@ -28,7 +29,7 @@ use thiserror::Error;
/// This trait is generally used in concert with [`AssetReader`](crate::io::AssetReader) to load assets from a byte source.
///
/// For a complementary version of this trait that can save assets, see [`AssetSaver`](crate::saver::AssetSaver).
pub trait AssetLoader: Send + Sync + 'static {
pub trait AssetLoader: TypePath + Send + Sync + 'static {
/// The top level [`Asset`] loaded by this [`AssetLoader`].
type Asset: Asset;
/// The settings type used by this [`AssetLoader`].
Expand Down Expand Up @@ -66,8 +67,8 @@ pub trait ErasedAssetLoader: Send + Sync + 'static {
fn deserialize_meta(&self, meta: &[u8]) -> Result<Box<dyn AssetMetaDyn>, DeserializeMetaError>;
/// Returns the default meta value for the [`AssetLoader`] (erased as [`Box<dyn AssetMetaDyn>`]).
fn default_meta(&self) -> Box<dyn AssetMetaDyn>;
/// Returns the type name of the [`AssetLoader`].
fn type_name(&self) -> &'static str;
/// Returns the type path of the [`AssetLoader`].
fn type_path(&self) -> &'static str;
/// Returns the [`TypeId`] of the [`AssetLoader`].
fn type_id(&self) -> TypeId;
/// Returns the type name of the top-level [`Asset`] loaded by the [`AssetLoader`].
Expand Down Expand Up @@ -111,13 +112,13 @@ where

fn default_meta(&self) -> Box<dyn AssetMetaDyn> {
Box::new(AssetMeta::<L, ()>::new(crate::meta::AssetAction::Load {
loader: self.type_name().to_string(),
loader: self.type_path().to_string(),
settings: L::Settings::default(),
}))
}

fn type_name(&self) -> &'static str {
core::any::type_name::<L>()
fn type_path(&self) -> &'static str {
L::type_path()
}

fn type_id(&self) -> TypeId {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_asset/src/loader_builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ impl NestedLoader<'_, '_, StaticTyped, Immediate<'_, '_>> {
path,
requested: TypeId::of::<A>(),
actual_asset_name: loader.asset_type_name(),
loader_name: loader.type_name(),
loader_name: loader.type_path(),
},
})
})
Expand Down
Loading