diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index 9fa8eb4381..4a1d51a6ec 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -422,6 +422,11 @@ impl Assets { } } + #[inline] + pub fn get_many(&self, ids: [AssetId; N]) -> [Option<&A>; N] { + ids.map(|id| self.get(id)) + } + /// Retrieves a mutable reference to the [`Asset`] with the given `id`, if it exists. /// Note that this supports anything that implements `Into>`, which includes [`Handle`] and [`AssetId`]. #[inline] @@ -437,6 +442,39 @@ impl Assets { result } + #[inline] + #[allow(unsafe_code)] + pub fn get_many_mut( + &mut self, + ids: [AssetId; N], + ) -> Option<[Option<&mut A>; N]> { + use std::mem::MaybeUninit; + + // SAFETY: Verify that all entities are unique + for i in 0..N { + for j in 0..i { + if ids[i] == ids[j] { + return None; + } + } + } + + let mut values = [(); N].map(|_| MaybeUninit::uninit()); + + for (value, asset) in core::iter::zip(&mut values, ids) { + let item: Option<*mut _> = match self.get_mut(asset) { + Some(asset) => Some(asset), + None => None, + }; + + *value = MaybeUninit::new(item); + } + + // SAFETY: Each value has been fully initialized. + let values = values.map(|x| unsafe { x.assume_init().map(|raw| std::mem::transmute(raw)) }); + Some(values) + } + /// Removes (and returns) the [`Asset`] with the given `id`, if it exists. /// Note that this supports anything that implements `Into>`, which includes [`Handle`] and [`AssetId`]. pub fn remove(&mut self, id: impl Into>) -> Option {