diff --git a/CHANGELOG.md b/CHANGELOG.md index b2c6534..d715e73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.16.0 - 22.03.2026 - Add asset savers to all supported formats +- RON deserialization options customization [#61](https://github.com/NiklasEi/bevy_common_assets/pull/61) ## v0.15.0 - 14.01.2026 - Update to Bevy 0.18 diff --git a/assets/trees.level.ron b/assets/trees.level.ron index f5a8a0e..6b6fb26 100644 --- a/assets/trees.level.ron +++ b/assets/trees.level.ron @@ -6,5 +6,6 @@ (-61., 149., 0.), (-96., -52., 0.), (69., -189., 0.), - ] + ], + alpha: 0.5 ) diff --git a/examples/ron.rs b/examples/ron.rs index 941447b..0fd62d7 100644 --- a/examples/ron.rs +++ b/examples/ron.rs @@ -28,9 +28,15 @@ fn spawn_level( mut state: ResMut>, ) { if let Some(level) = levels.remove(level.0.id()) { + // Default to fully opaque if alpha is None. + let color = Color::default().with_alpha(level.alpha.unwrap_or(1.0)); for position in level.positions { commands.spawn(( - Sprite::from_image(tree.0.clone()), + Sprite { + image: tree.0.clone(), + color, + ..default() + }, Transform::from_translation(position.into()), )); } @@ -42,6 +48,7 @@ fn spawn_level( #[derive(serde::Deserialize, Asset, TypePath)] struct Level { positions: Vec<[f32; 3]>, + alpha: Option, } #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] diff --git a/src/ron.rs b/src/ron.rs index 912c3b0..3e9488f 100644 --- a/src/ron.rs +++ b/src/ron.rs @@ -3,13 +3,14 @@ use bevy_asset::io::Reader; use bevy_asset::{Asset, AssetApp, AssetLoader, AsyncWriteExt, LoadContext, saver::AssetSaver}; use bevy_reflect::TypePath; use serde::{Deserialize, Serialize}; -use serde_ron::de::from_bytes; +use serde_ron::{Options, extensions::Extensions}; use std::marker::PhantomData; use thiserror::Error; /// Plugin to load your asset type `A` from ron files. pub struct RonAssetPlugin { extensions: Vec<&'static str>, + options: Options, _marker: PhantomData, } @@ -21,6 +22,7 @@ where app.init_asset::() .register_asset_loader(RonAssetLoader:: { extensions: self.extensions.clone(), + options: self.options.clone(), _marker: PhantomData, }); } @@ -31,18 +33,44 @@ where for<'de> A: serde::Deserialize<'de> + Asset, { /// Create a new plugin that will load assets from files with the given extensions. + /// + /// Enables [`Extensions::IMPLICIT_SOME`] by default. pub fn new(extensions: &[&'static str]) -> Self { Self { extensions: extensions.to_owned(), + options: Options::default().with_default_extension(Extensions::IMPLICIT_SOME), _marker: PhantomData, } } + + /// Customize RON deserialization options. + /// + /// ```no_run + /// # use bevy::prelude::*; + /// # use bevy_common_assets::ron::RonAssetPlugin; + /// use serde_ron::{extensions::Extensions, Options}; + /// + /// App::new() + /// .add_plugins(RonAssetPlugin::::new(&["level.ron"]) + /// .with_options(Options::default().with_default_extension( + /// Extensions::UNWRAP_NEWTYPES | Extensions::IMPLICIT_SOME, + /// ))); + /// # #[derive(serde::Deserialize, Asset, TypePath)] + /// # struct Level { + /// # value: Option, + /// # } + /// ``` + pub fn with_options(mut self, options: Options) -> Self { + self.options = options; + self + } } /// Loads your asset type `A` from ron files #[derive(TypePath)] pub struct RonAssetLoader { extensions: Vec<&'static str>, + options: Options, _marker: PhantomData, } @@ -81,7 +109,7 @@ where ) -> Result { let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await?; - let asset = from_bytes::(&bytes)?; + let asset = self.options.from_bytes::(&bytes)?; Ok(asset) }