Skip to content

Commit 3b73527

Browse files
committed
Store the asset processors by their short type path as well and check the short path first.
1 parent 39ca46e commit 3b73527

File tree

2 files changed

+94
-7
lines changed

2 files changed

+94
-7
lines changed

crates/bevy_asset/src/processor/mod.rs

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ use crate::{
5858
AssetLoadError, AssetMetaCheck, AssetPath, AssetServer, AssetServerMode, DeserializeMetaError,
5959
MissingAssetLoaderForExtensionError, UnapprovedPathMode, WriteDefaultMetaError,
6060
};
61-
use alloc::{borrow::ToOwned, boxed::Box, collections::VecDeque, sync::Arc, vec, vec::Vec};
61+
use alloc::{
62+
borrow::ToOwned, boxed::Box, collections::VecDeque, string::String, sync::Arc, vec, vec::Vec,
63+
};
6264
use bevy_ecs::prelude::*;
6365
use bevy_platform::{
64-
collections::{HashMap, HashSet},
66+
collections::{hash_map::Entry, HashMap, HashSet},
6567
sync::{PoisonError, RwLock},
6668
};
6769
use bevy_tasks::IoTaskPool;
@@ -117,11 +119,27 @@ pub struct AssetProcessorData {
117119
struct Processors {
118120
/// Maps the type path of the processor to its instance.
119121
type_path_to_processor: HashMap<&'static str, Arc<dyn ErasedProcessor>>,
122+
/// Maps the short type path of the processor to its instance.
123+
short_type_path_to_processor: HashMap<&'static str, ShortTypeProcessorEntry>,
120124
/// Maps the file extension of an asset to the type path of the processor we should use to
121125
/// process it by default.
122126
file_extension_to_default_processor: HashMap<Box<str>, &'static str>,
123127
}
124128

129+
enum ShortTypeProcessorEntry {
130+
/// There is a unique processor with the given short type path.
131+
Unique {
132+
/// The full type path of the processor.
133+
type_path: &'static str,
134+
/// The processor itself.
135+
processor: Arc<dyn ErasedProcessor>,
136+
},
137+
/// There are (at least) two processors with the same short type path (storing the full type
138+
/// paths of all conflicting processors). Users must fully specify the type path in order to
139+
/// disambiguate.
140+
Ambiguous(Vec<&'static str>),
141+
}
142+
125143
impl AssetProcessor {
126144
/// Creates a new [`AssetProcessor`] instance.
127145
pub fn new(source: &mut AssetSourceBuilders) -> Self {
@@ -600,9 +618,31 @@ impl AssetProcessor {
600618
.unwrap_or_else(PoisonError::into_inner);
601619
#[cfg(feature = "trace")]
602620
let processor = InstrumentedAssetProcessor(processor);
621+
let processor = Arc::new(processor);
603622
processors
604623
.type_path_to_processor
605-
.insert(P::type_path(), Arc::new(processor));
624+
.insert(P::type_path(), processor.clone());
625+
match processors
626+
.short_type_path_to_processor
627+
.entry(P::short_type_path())
628+
{
629+
Entry::Vacant(entry) => {
630+
entry.insert(ShortTypeProcessorEntry::Unique {
631+
type_path: P::type_path(),
632+
processor,
633+
});
634+
}
635+
Entry::Occupied(mut entry) => match entry.get_mut() {
636+
ShortTypeProcessorEntry::Unique { type_path, .. } => {
637+
let type_path = *type_path;
638+
*entry.get_mut() =
639+
ShortTypeProcessorEntry::Ambiguous(vec![type_path, P::type_path()]);
640+
}
641+
ShortTypeProcessorEntry::Ambiguous(type_paths) => {
642+
type_paths.push(P::type_path());
643+
}
644+
},
645+
}
606646
}
607647

608648
/// Set the default processor for the given `extension`. Make sure `P` is registered with [`AssetProcessor::register_processor`].
@@ -631,16 +671,32 @@ impl AssetProcessor {
631671
}
632672

633673
/// Returns the processor with the given `processor_type_name`, if it exists.
634-
pub fn get_processor(&self, processor_type_name: &str) -> Option<Arc<dyn ErasedProcessor>> {
674+
pub fn get_processor(
675+
&self,
676+
processor_type_name: &str,
677+
) -> Result<Arc<dyn ErasedProcessor>, GetProcessorError> {
635678
let processors = self
636679
.data
637680
.processors
638681
.read()
639682
.unwrap_or_else(PoisonError::into_inner);
683+
if let Some(short_type_processor) = processors
684+
.short_type_path_to_processor
685+
.get(processor_type_name)
686+
{
687+
return match short_type_processor {
688+
ShortTypeProcessorEntry::Unique { processor, .. } => Ok(processor.clone()),
689+
ShortTypeProcessorEntry::Ambiguous(examples) => Err(GetProcessorError::Ambiguous {
690+
processor_short_name: processor_type_name.to_owned(),
691+
ambiguous_processor_names: examples.clone(),
692+
}),
693+
};
694+
}
640695
processors
641696
.type_path_to_processor
642697
.get(processor_type_name)
643698
.cloned()
699+
.ok_or_else(|| GetProcessorError::Missing(processor_type_name.to_owned()))
644700
}
645701

646702
/// Populates the initial view of each asset by scanning the unprocessed and processed asset folders.
@@ -864,9 +920,7 @@ impl AssetProcessor {
864920
(meta, None)
865921
}
866922
AssetActionMinimal::Process { processor } => {
867-
let processor = self
868-
.get_processor(&processor)
869-
.ok_or_else(|| ProcessError::MissingProcessor(processor))?;
923+
let processor = self.get_processor(&processor)?;
870924
let meta = processor.deserialize_meta(&meta_bytes)?;
871925
(meta, Some(processor))
872926
}
@@ -1511,3 +1565,30 @@ pub enum InitializeError {
15111565
#[error("Failed to validate asset log: {0}")]
15121566
ValidateLogError(#[from] ValidateLogError),
15131567
}
1568+
1569+
/// An error when retrieving an asset processor.
1570+
#[derive(Error, Debug)]
1571+
pub enum GetProcessorError {
1572+
#[error("The processor '{0}' does not exist")]
1573+
Missing(String),
1574+
#[error("The processor '{processor_short_name}' is ambiguous between several processors: {ambiguous_processor_names:?}")]
1575+
Ambiguous {
1576+
processor_short_name: String,
1577+
ambiguous_processor_names: Vec<&'static str>,
1578+
},
1579+
}
1580+
1581+
impl From<GetProcessorError> for ProcessError {
1582+
fn from(err: GetProcessorError) -> Self {
1583+
match err {
1584+
GetProcessorError::Missing(name) => Self::MissingProcessor(name),
1585+
GetProcessorError::Ambiguous {
1586+
processor_short_name,
1587+
ambiguous_processor_names,
1588+
} => Self::AmbiguousProcessor {
1589+
processor_short_name,
1590+
ambiguous_processor_names,
1591+
},
1592+
}
1593+
}
1594+
}

crates/bevy_asset/src/processor/process.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use alloc::{
1414
borrow::ToOwned,
1515
boxed::Box,
1616
string::{String, ToString},
17+
vec::Vec,
1718
};
1819
use bevy_reflect::TypePath;
1920
use bevy_tasks::{BoxedFuture, ConditionalSendFuture};
@@ -122,6 +123,11 @@ pub enum ProcessError {
122123
#[error("The processor '{0}' does not exist")]
123124
#[from(ignore)]
124125
MissingProcessor(String),
126+
#[error("The processor '{processor_short_name}' is ambiguous between several processors: {ambiguous_processor_names:?}")]
127+
AmbiguousProcessor {
128+
processor_short_name: String,
129+
ambiguous_processor_names: Vec<&'static str>,
130+
},
125131
#[error("Encountered an AssetReader error for '{path}': {err}")]
126132
#[from(ignore)]
127133
AssetReaderError {

0 commit comments

Comments
 (0)