Skip to content

Commit f840ae7

Browse files
committed
feat: Support array of StandardDynamicAsset via Ron
1 parent c0a0fa0 commit f840ae7

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

bevy_asset_loader/src/standard_dynamic_asset.rs

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

Comments
 (0)