@@ -302,10 +302,104 @@ 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+ ///
379+ /// struct MyAssets {
380+ /// #[asset(key = "layouts", collection(typed))]
381+ /// atlas_layout: Vec<Handle<TextureAtlasLayout>>,
382+ ///
383+ /// #[asset(key = "mixed", collection)]
384+ /// mixed_handlers: Vec<UntypedHandle>,
385+ /// }
386+ /// ```
387+ #[ derive( Deserialize , Serialize , Asset , TypePath , PartialEq , Debug ) ]
388+ pub struct StandardDynamicAssetArrayCollection ( HashMap < String , Vec < StandardDynamicAsset > > ) ;
389+
390+ impl DynamicAssetCollection for StandardDynamicAssetArrayCollection {
391+ fn register ( & self , dynamic_assets : & mut DynamicAssets ) {
392+ for ( key, asset) in self . 0 . iter ( ) {
393+ dynamic_assets. register_asset ( key, Box :: new ( asset. clone ( ) ) ) ;
394+ }
395+ }
396+ }
397+
305398#[ cfg( test) ]
306399#[ cfg( feature = "2d" ) ]
307400mod tests {
308401 use crate :: prelude:: StandardDynamicAssetCollection ;
402+ use crate :: standard_dynamic_asset:: StandardDynamicAssetArrayCollection ;
309403
310404 #[ test]
311405 fn serialize_and_deserialize_atlas ( ) {
@@ -332,6 +426,62 @@ mod tests {
332426 serialize_and_deserialize ( dynamic_asset_file) ;
333427 }
334428
429+ #[ test]
430+ fn serialize_and_deserialize_array ( ) {
431+ let dynamic_asset_file = r#"({
432+ "layouts": [
433+ TextureAtlasLayout(
434+ tile_size_x: 32.0,
435+ tile_size_y: 32.0,
436+ columns: 12,
437+ rows: 12,
438+ ),
439+ TextureAtlasLayout(
440+ tile_size_x: 32.0,
441+ tile_size_y: 64.0,
442+ columns: 12,
443+ rows: 6,
444+ ),
445+ TextureAtlasLayout(
446+ tile_size_x: 64.0,
447+ tile_size_y: 32.0,
448+ columns: 6,
449+ rows: 12,
450+ ),
451+ TextureAtlasLayout(
452+ tile_size_x: 64.0,
453+ tile_size_y: 64.0,
454+ columns: 6,
455+ rows: 6,
456+ ),
457+ ],
458+ "mixed": [
459+ StandardMaterial(
460+ path: "images/tree.png",
461+ ),
462+ Image(
463+ path: "ryot_mascot.png",
464+ sampler: Nearest,
465+ ),
466+ Image(
467+ path: "ryot_mascot.png",
468+ sampler: Nearest,
469+ ),
470+ ],
471+ })"# ;
472+
473+ let before: StandardDynamicAssetArrayCollection =
474+ ron:: from_str ( dynamic_asset_file) . unwrap ( ) ;
475+
476+ let serialized_dynamic_asset_file = ron:: ser:: to_string_pretty (
477+ & before,
478+ ron:: ser:: PrettyConfig :: default ( ) . new_line ( "\n " . to_string ( ) ) ,
479+ )
480+ . unwrap ( ) ;
481+
482+ assert_eq ! ( dynamic_asset_file, & serialized_dynamic_asset_file) ;
483+ }
484+
335485 fn serialize_and_deserialize ( dynamic_asset_file : & ' static str ) {
336486 let before: StandardDynamicAssetCollection = ron:: from_str ( dynamic_asset_file) . unwrap ( ) ;
337487
0 commit comments