@@ -302,10 +302,106 @@ impl DynamicAssetCollection for StandardDynamicAssetCollection {
302302 }
303303}
304304
305+ impl DynamicAsset for Vec < StandardDynamicAsset > {
306+ fn load ( & self , asset_server : & AssetServer ) -> Vec < UntypedHandle > {
307+ self . iter ( )
308+ . flat_map ( |asset| asset. load ( asset_server) )
309+ . collect ( )
310+ }
311+
312+ fn build ( & self , world : & mut World ) -> Result < DynamicAssetType , anyhow:: Error > {
313+ let mut all_handles = vec ! [ ] ;
314+
315+ for asset in self {
316+ match asset. build ( world) ? {
317+ DynamicAssetType :: Single ( handle) => all_handles. push ( handle) ,
318+ DynamicAssetType :: Collection ( handles) => all_handles. extend ( handles) ,
319+ }
320+ }
321+
322+ Ok ( DynamicAssetType :: Collection ( all_handles) )
323+ }
324+ }
325+
326+ /// The asset defining a mapping from asset keys to an array of dynamic assets.
327+ ///
328+ /// These assets are loaded at the beginning of a loading state
329+ /// and combined in [`DynamicAssets`].
330+ ///
331+ /// Example:
332+ /// ```ron
333+ /// ({
334+ /// "layouts": [
335+ /// TextureAtlasLayout(
336+ /// tile_size_x: 32.,
337+ /// tile_size_y: 32.,
338+ /// columns: 12,
339+ /// rows: 12,
340+ /// ),
341+ /// TextureAtlasLayout(
342+ /// tile_size_x: 32.,
343+ /// tile_size_y: 64.,
344+ /// columns: 12,
345+ /// rows: 6,
346+ /// ),
347+ /// TextureAtlasLayout(
348+ /// tile_size_x: 64.,
349+ /// tile_size_y: 32.,
350+ /// columns: 6,
351+ /// rows: 12,
352+ /// ),
353+ /// TextureAtlasLayout(
354+ /// tile_size_x: 64.,
355+ /// tile_size_y: 64.,
356+ /// columns: 6,
357+ /// rows: 6,
358+ /// ),
359+ /// ],
360+ /// "mixed": [
361+ /// StandardMaterial(
362+ /// path: "images/tree.png",
363+ /// ),
364+ /// Image(
365+ /// path: "ryot_mascot.png",
366+ /// sampler: Nearest,
367+ /// ),
368+ /// Image(
369+ /// path: "ryot_mascot.png",
370+ /// sampler: Nearest,
371+ /// ),
372+ /// ],
373+ /// })
374+ /// ```
375+ ///
376+ /// ```rust
377+ /// # use bevy::prelude::*;
378+ /// # use bevy_asset_loader::prelude::*;
379+ ///
380+ /// #[derive(AssetCollection, Resource)]
381+ /// struct MyAssets {
382+ /// #[asset(key = "layouts", collection(typed))]
383+ /// atlas_layout: Vec<Handle<TextureAtlasLayout>>,
384+ ///
385+ /// #[asset(key = "mixed", collection)]
386+ /// mixed_handlers: Vec<UntypedHandle>,
387+ /// }
388+ /// ```
389+ #[ derive( Deserialize , Serialize , Asset , TypePath , PartialEq , Debug ) ]
390+ pub struct StandardDynamicAssetArrayCollection ( HashMap < String , Vec < StandardDynamicAsset > > ) ;
391+
392+ impl DynamicAssetCollection for StandardDynamicAssetArrayCollection {
393+ fn register ( & self , dynamic_assets : & mut DynamicAssets ) {
394+ for ( key, asset) in self . 0 . iter ( ) {
395+ dynamic_assets. register_asset ( key, Box :: new ( asset. clone ( ) ) ) ;
396+ }
397+ }
398+ }
399+
305400#[ cfg( test) ]
306401#[ cfg( feature = "2d" ) ]
307402mod tests {
308403 use crate :: prelude:: StandardDynamicAssetCollection ;
404+ use crate :: standard_dynamic_asset:: StandardDynamicAssetArrayCollection ;
309405
310406 #[ test]
311407 fn serialize_and_deserialize_atlas ( ) {
@@ -332,6 +428,62 @@ mod tests {
332428 serialize_and_deserialize ( dynamic_asset_file) ;
333429 }
334430
431+ #[ test]
432+ fn serialize_and_deserialize_array ( ) {
433+ let dynamic_asset_file = r#"({
434+ "layouts": [
435+ TextureAtlasLayout(
436+ tile_size_x: 32.0,
437+ tile_size_y: 32.0,
438+ columns: 12,
439+ rows: 12,
440+ ),
441+ TextureAtlasLayout(
442+ tile_size_x: 32.0,
443+ tile_size_y: 64.0,
444+ columns: 12,
445+ rows: 6,
446+ ),
447+ TextureAtlasLayout(
448+ tile_size_x: 64.0,
449+ tile_size_y: 32.0,
450+ columns: 6,
451+ rows: 12,
452+ ),
453+ TextureAtlasLayout(
454+ tile_size_x: 64.0,
455+ tile_size_y: 64.0,
456+ columns: 6,
457+ rows: 6,
458+ ),
459+ ],
460+ "mixed": [
461+ StandardMaterial(
462+ path: "images/tree.png",
463+ ),
464+ Image(
465+ path: "ryot_mascot.png",
466+ sampler: Nearest,
467+ ),
468+ Image(
469+ path: "ryot_mascot.png",
470+ sampler: Nearest,
471+ ),
472+ ],
473+ })"# ;
474+
475+ let before: StandardDynamicAssetArrayCollection =
476+ ron:: from_str ( dynamic_asset_file) . unwrap ( ) ;
477+
478+ let serialized_dynamic_asset_file = ron:: ser:: to_string_pretty (
479+ & before,
480+ ron:: ser:: PrettyConfig :: default ( ) . new_line ( "\n " . to_string ( ) ) ,
481+ )
482+ . unwrap ( ) ;
483+
484+ assert_eq ! ( dynamic_asset_file, & serialized_dynamic_asset_file) ;
485+ }
486+
335487 fn serialize_and_deserialize ( dynamic_asset_file : & ' static str ) {
336488 let before: StandardDynamicAssetCollection = ron:: from_str ( dynamic_asset_file) . unwrap ( ) ;
337489
0 commit comments