From 2eb6d764a7da6764b27c1902478c89e06dadb8c4 Mon Sep 17 00:00:00 2001 From: andriyDev Date: Fri, 19 Dec 2025 18:26:37 -0800 Subject: [PATCH 1/2] Allow the default process write to write a short type name for the processor name. --- crates/bevy_asset/src/processor/mod.rs | 16 +++++++++++++-- crates/bevy_asset/src/processor/process.rs | 24 +++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/crates/bevy_asset/src/processor/mod.rs b/crates/bevy_asset/src/processor/mod.rs index b43bab28758ed..97f88431efd52 100644 --- a/crates/bevy_asset/src/processor/mod.rs +++ b/crates/bevy_asset/src/processor/mod.rs @@ -445,7 +445,16 @@ impl AssetProcessor { .await; }; - let meta = processor.default_meta(); + let short_type_path = processor.short_type_path(); + // Try to get the processor using the short type - if it fails, that must mean that the + // short type path is insufficient, so we'll have to fall back to the long path. + let processor_path_kind = if self.get_processor(short_type_path).is_ok() { + MetaTypePathKind::Short + } else { + MetaTypePathKind::Long + }; + + let meta = processor.default_meta(processor_path_kind); let serialized_meta = meta.serialize(); let source = self.get_source(path.source())?; @@ -1078,7 +1087,10 @@ impl AssetProcessor { .get_full_extension() .and_then(|ext| self.get_default_processor(&ext)) { - let meta = processor.default_meta(); + // Note: It doesn't matter whether we use the Long or Short kind, since we're + // returning the processor here anyway, and we're only using this meta to pass + // along the processor settings. + let meta = processor.default_meta(MetaTypePathKind::Long); (meta, Some(processor)) } else { match server.get_path_asset_loader(asset_path.clone()).await { diff --git a/crates/bevy_asset/src/processor/process.rs b/crates/bevy_asset/src/processor/process.rs index 80f0e8a2eb878..2d6ce1ddd5cc5 100644 --- a/crates/bevy_asset/src/processor/process.rs +++ b/crates/bevy_asset/src/processor/process.rs @@ -247,8 +247,18 @@ pub trait ErasedProcessor: Send + Sync { fn deserialize_meta(&self, meta: &[u8]) -> Result, DeserializeMetaError>; /// Returns the type-path of the original [`Process`]. fn type_path(&self) -> &'static str; + /// Returns the short type path of this processor. + fn short_type_path(&self) -> &'static str; /// Returns the default type-erased [`AssetMeta`] for the underlying [`Process`] impl. - fn default_meta(&self) -> Box; + fn default_meta(&self, processor_path_kind: MetaTypePathKind) -> Box; +} + +/// Specifies which kind of path to use to specify a type. +pub enum MetaTypePathKind { + /// Use the short type path. + Short, + /// Use the fully-qualified type path. + Long, } impl ErasedProcessor for P { @@ -287,9 +297,17 @@ impl ErasedProcessor for P { P::type_path() } - fn default_meta(&self) -> Box { + fn short_type_path(&self) -> &'static str { + P::short_type_path() + } + + fn default_meta(&self, processor_path_kind: MetaTypePathKind) -> Box { + let type_path = match processor_path_kind { + MetaTypePathKind::Short => P::short_type_path(), + MetaTypePathKind::Long => P::type_path(), + }; Box::new(AssetMeta::<(), P>::new(AssetAction::Process { - processor: P::type_path().to_string(), + processor: type_path.to_string(), settings: P::Settings::default(), })) } From 3ae014f456d262535ccbcb848d6bf1d3ea9eb284 Mon Sep 17 00:00:00 2001 From: andriyDev Date: Fri, 19 Dec 2025 18:26:37 -0800 Subject: [PATCH 2/2] Write tests for the short type path, and fallback to the long type path. --- crates/bevy_asset/src/processor/tests.rs | 72 +++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/crates/bevy_asset/src/processor/tests.rs b/crates/bevy_asset/src/processor/tests.rs index 5a02b819e098b..5e486de87fd6a 100644 --- a/crates/bevy_asset/src/processor/tests.rs +++ b/crates/bevy_asset/src/processor/tests.rs @@ -1733,7 +1733,7 @@ fn only_reprocesses_wrong_hash_on_startup() { } #[test] -fn writes_default_meta_for_processor() { +fn writes_short_default_meta_for_processor() { let AppWithProcessor { mut app, default_source_dirs: ProcessingDirs { source, .. }, @@ -1758,6 +1758,76 @@ fn writes_default_meta_for_processor() { let processor = app.world().resource::().clone(); bevy_tasks::block_on(processor.write_default_meta_file_for_path(ASSET_PATH)).unwrap(); + assert_eq!( + read_meta_as_string(&source, Path::new(ASSET_PATH)), + r#"( + meta_format_version: "1.0", + asset: Process( + processor: "LoadTransformAndSave, CoolTextSaver>", + settings: ( + loader_settings: (), + transformer_settings: (), + saver_settings: (), + ), + ), +)"# + ); +} + +mod ambiguous { + use super::{CoolText, MutateAsset, TypePath}; + + /// This is ambiguous with [`super::AddText`] for short-type paths. + #[derive(TypePath)] + pub(crate) struct AddText; + + // Add a dummy MutateAsset impl so we can use it as a processor. + impl MutateAsset for AddText { + fn mutate(&self, _: &mut CoolText) {} + } +} + +#[test] +fn writes_long_default_meta_for_ambiguous_processor() { + let AppWithProcessor { + mut app, + default_source_dirs: ProcessingDirs { source, .. }, + .. + } = create_app_with_asset_processor(&[]); + + type CoolTextProcessor1 = LoadTransformAndSave< + CoolTextLoader, + RootAssetTransformer, + CoolTextSaver, + >; + type CoolTextProcessor2 = LoadTransformAndSave< + CoolTextLoader, + RootAssetTransformer, + CoolTextSaver, + >; + // Verify that these two processors actually have the same short_type_path. + assert_eq!( + CoolTextProcessor1::short_type_path(), + CoolTextProcessor2::short_type_path() + ); + + app.register_asset_processor(CoolTextProcessor1::new( + RootAssetTransformer::new(AddText("blah".to_string())), + CoolTextSaver, + )) + .set_default_asset_processor::("cool.ron") + // Add another processor with the same short type path to make the short type name ambiguous. + .register_asset_processor(CoolTextProcessor2::new( + RootAssetTransformer::new(ambiguous::AddText), + CoolTextSaver, + )); + + const ASSET_PATH: &str = "abc.cool.ron"; + source.insert_asset_text(Path::new(ASSET_PATH), &serialize_as_cool_text("blah")); + + let processor = app.world().resource::().clone(); + bevy_tasks::block_on(processor.write_default_meta_file_for_path(ASSET_PATH)).unwrap(); + assert_eq!( read_meta_as_string(&source, Path::new(ASSET_PATH)), r#"(