Skip to content

Commit d9b09db

Browse files
committed
feat: Support array of StandardDynamicAsset via Ron
1 parent 5971c0c commit d9b09db

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

bevy_asset_loader/src/standard_dynamic_asset.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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")]
307400
mod 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

Comments
 (0)