diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9453f045..84565051 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,6 +23,7 @@ env: CARGO_TERM_COLOR: always jobs: + build: strategy: matrix: @@ -52,36 +53,36 @@ jobs: with: components: rustfmt, clippy - name: Build & run lib tests (${{ matrix.dimensions }} no GPU) - run: cargo test --lib --no-default-features --features ${{ matrix.dimensions }} + run: cargo test --lib --no-default-features --features ${{ matrix.dimensions }} --features serde env: CARGO_INCREMENTAL: 0 if: runner.os == 'linux' && matrix.dimensions != 'all' - name: Build & run lib tests (${{ matrix.dimensions }} DX12) shell: bash - run: WGPU_BACKEND=dx12 cargo test --lib --no-default-features --features ${{ matrix.dimensions }} --features gpu_tests + run: WGPU_BACKEND=dx12 cargo test --lib --no-default-features --features ${{ matrix.dimensions }} --features serde,gpu_tests env: CARGO_INCREMENTAL: 0 if: runner.os == 'windows' && matrix.dimensions != 'all' - name: Build & run all tests (${{ matrix.dimensions }} METAL) shell: bash - run: WGPU_BACKEND=metal cargo test --no-default-features --features ${{ matrix.dimensions }} --features gpu_tests + run: WGPU_BACKEND=metal cargo test --no-default-features --features ${{ matrix.dimensions }} --features serde,gpu_tests env: CARGO_INCREMENTAL: 0 if: runner.os == 'macos' && matrix.dimensions != 'all' - name: Build & run lib tests (all no GPU) - run: cargo test --lib --no-default-features --features "2d 3d" + run: cargo test --lib --no-default-features --features "2d 3d serde" env: CARGO_INCREMENTAL: 0 if: runner.os == 'linux' && matrix.dimensions == 'all' - name: Build & run lib tests (all DX12) shell: bash - run: WGPU_BACKEND=dx12 cargo test --lib --no-default-features --features "2d 3d gpu_tests" + run: WGPU_BACKEND=dx12 cargo test --lib --no-default-features --features "2d 3d serde gpu_tests" env: CARGO_INCREMENTAL: 0 if: runner.os == 'windows' && matrix.dimensions == 'all' - name: Build & run all tests (all METAL) shell: bash - run: WGPU_BACKEND=metal cargo test --no-default-features --features "2d 3d gpu_tests" + run: WGPU_BACKEND=metal cargo test --no-default-features --features "2d 3d serde gpu_tests" env: CARGO_INCREMENTAL: 0 if: runner.os == 'macos' && matrix.dimensions == 'all' @@ -123,19 +124,19 @@ jobs: for example in .github/example-run/3d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font 3d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font 3d serde bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/3dpng/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font bevy/png 3d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font bevy/png 3d serde bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/2d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite bevy/bevy_ui bevy/default_font 2d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite bevy/bevy_ui bevy/default_font 2d serde bevy/bevy_ci_testing" sleep 10 done env: @@ -147,19 +148,19 @@ jobs: for example in .github/example-run/3d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font 3d bevy/bevy_ci_testing" + time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font 3d serde bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/3dpng/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font bevy/png 3d bevy/bevy_ci_testing" + time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font bevy/png 3d serde bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/2d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite bevy/bevy_ui bevy/default_font 2d bevy/bevy_ci_testing" + time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite bevy/bevy_ui bevy/default_font 2d serde bevy/bevy_ci_testing" sleep 10 done env: diff --git a/Cargo.toml b/Cargo.toml index 28a6c066..7b55060d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ exclude = ["docs/*.svg", "docs/*.png", "examples/*.gif", "examples/*.png", ".git autoexamples = false [features] -default = ["2d", "3d", "gpu_tests", "examples_world_inspector"] +default = ["2d", "3d", "serde", "gpu_tests", "examples_world_inspector"] # Enable support for rendering through a 2D camera (Camera2dBundle) 2d = [] @@ -22,6 +22,9 @@ default = ["2d", "3d", "gpu_tests", "examples_world_inspector"] # Enable support for rendering through a 3D camera (Camera3dBundle) 3d = [] +# Enable serializing and deserializing of assets. +serde = ["typetag"] + # Enable tracing annotations trace = [] @@ -48,7 +51,7 @@ serde = { version = "1.0", features = ["derive"] } anyhow = "1.0" ron = "0.8" bitflags = "2.3" -typetag = "0.2" +typetag = { version = "0.2", optional = true } thiserror = "1.0" # Same versions as Bevy 0.14 (bevy_render) naga = "0.20" diff --git a/src/asset.rs b/src/asset.rs index 25734742..75d8c39e 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -1,13 +1,18 @@ use std::ops::Deref; use bevy::{ - asset::{io::Reader, Asset, AssetLoader, AsyncReadExt, LoadContext}, + asset::Asset, reflect::Reflect, utils::{default, HashSet}, }; -use serde::{Deserialize, Serialize}; + +#[cfg(feature = "serde")] +use bevy::asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext}; +#[cfg(feature = "serde")] use thiserror::Error; +use serde::{Deserialize, Serialize}; + use crate::{ modifier::{Modifier, RenderModifier}, ExprHandle, GroupedModifier, ModifierContext, Module, ParticleGroupSet, ParticleLayout, @@ -202,7 +207,8 @@ pub enum AlphaMode { /// /// [`ParticleEffect`]: crate::ParticleEffect /// [`ParticleEffectBundle`]: crate::ParticleEffectBundle -#[derive(Asset, Default, Clone, Reflect, Serialize, Deserialize)] +#[derive(Asset, Default, Clone, Reflect)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[reflect(from_reflect = false)] pub struct EffectAsset { /// Display name of the effect. @@ -709,10 +715,12 @@ impl EffectAsset { /// Asset loader for [`EffectAsset`]. /// /// Effet assets take the `.effect` extension. +#[cfg(feature = "serde")] #[derive(Default)] pub struct EffectAssetLoader; /// Error for the [`EffectAssetLoader`] loading an [`EffectAsset`]. +#[cfg(feature = "serde")] #[derive(Error, Debug)] pub enum EffectAssetLoaderError { /// I/O error reading the asset source. @@ -724,6 +732,7 @@ pub enum EffectAssetLoaderError { Ron(#[from] ron::error::SpannedError), } +#[cfg(feature = "serde")] impl AssetLoader for EffectAssetLoader { type Asset = EffectAsset; @@ -750,6 +759,7 @@ impl AssetLoader for EffectAssetLoader { #[cfg(test)] mod tests { + #[cfg(feature = "serde")] use ron::ser::PrettyConfig; use super::*; @@ -861,6 +871,7 @@ mod tests { // assert_eq!(effect.render_layout, render_layout); } + #[cfg(feature = "serde")] #[test] fn test_serde_ron() { let w = ExprWriter::new(); diff --git a/src/modifier/accel.rs b/src/modifier/accel.rs index bf8f2bb7..13bdbd68 100644 --- a/src/modifier/accel.rs +++ b/src/modifier/accel.rs @@ -63,7 +63,7 @@ impl AccelModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for AccelModifier { fn context(&self) -> ModifierContext { ModifierContext::Update @@ -147,7 +147,7 @@ impl RadialAccelModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for RadialAccelModifier { fn context(&self) -> ModifierContext { ModifierContext::Update @@ -267,7 +267,7 @@ impl TangentAccelModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for TangentAccelModifier { fn context(&self) -> ModifierContext { ModifierContext::Update diff --git a/src/modifier/attr.rs b/src/modifier/attr.rs index e84aef6b..1003ed30 100644 --- a/src/modifier/attr.rs +++ b/src/modifier/attr.rs @@ -94,7 +94,7 @@ impl SetAttributeModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetAttributeModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update diff --git a/src/modifier/clone.rs b/src/modifier/clone.rs index 7bc9fa93..998b747f 100644 --- a/src/modifier/clone.rs +++ b/src/modifier/clone.rs @@ -28,7 +28,7 @@ pub struct CloneModifier { pub destination_group: u32, } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for CloneModifier { fn context(&self) -> ModifierContext { ModifierContext::Update diff --git a/src/modifier/force.rs b/src/modifier/force.rs index 30382aaf..8e88b728 100644 --- a/src/modifier/force.rs +++ b/src/modifier/force.rs @@ -159,7 +159,7 @@ impl ConformToSphereModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for ConformToSphereModifier { fn context(&self) -> ModifierContext { ModifierContext::Update @@ -269,7 +269,7 @@ impl LinearDragModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for LinearDragModifier { fn context(&self) -> ModifierContext { ModifierContext::Update diff --git a/src/modifier/kill.rs b/src/modifier/kill.rs index 9ad75bde..be706ad0 100644 --- a/src/modifier/kill.rs +++ b/src/modifier/kill.rs @@ -60,7 +60,7 @@ impl KillSphereModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for KillSphereModifier { fn context(&self) -> ModifierContext { ModifierContext::Update @@ -141,7 +141,7 @@ impl KillAabbModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for KillAabbModifier { fn context(&self) -> ModifierContext { ModifierContext::Update diff --git a/src/modifier/mod.rs b/src/modifier/mod.rs index b7118d5f..b49b1406 100644 --- a/src/modifier/mod.rs +++ b/src/modifier/mod.rs @@ -130,7 +130,7 @@ impl std::fmt::Display for ModifierContext { } /// Trait describing a modifier customizing an effect pipeline. -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] pub trait Modifier: Reflect + Send + Sync + 'static { /// Get the context this modifier applies to. fn context(&self) -> ModifierContext; @@ -209,7 +209,8 @@ impl ParticleGroupSet { } /// A [`Modifier`] that affects to one or more groups. -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct GroupedModifier { /// The modifier. pub modifier: BoxedModifier, @@ -535,7 +536,7 @@ impl<'a> EvalContext for RenderContext<'a> { } /// Trait to customize the rendering of alive particles each frame. -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] pub trait RenderModifier: Modifier { /// Apply the rendering code. fn apply_render(&self, module: &mut Module, context: &mut RenderContext); @@ -556,7 +557,7 @@ impl Clone for Box { /// Macro to implement the [`Modifier`] trait for a render modifier. macro_rules! impl_mod_render { ($t:ty, $attrs:expr) => { - #[typetag::serde] + #[cfg_attr(feature = "serde", typetag::serde)] impl $crate::Modifier for $t { fn context(&self) -> $crate::ModifierContext { $crate::ModifierContext::Render @@ -648,6 +649,7 @@ mod tests { assert_eq!(*m_reflect, m); } + #[cfg(feature = "serde")] #[test] fn serde() { let m = make_test_modifier(); diff --git a/src/modifier/output.rs b/src/modifier/output.rs index 925531ac..40851b38 100644 --- a/src/modifier/output.rs +++ b/src/modifier/output.rs @@ -77,7 +77,7 @@ pub struct ParticleTextureModifier { impl_mod_render!(ParticleTextureModifier, &[]); // TODO - should require some UV maybe? -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for ParticleTextureModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { context.set_particle_texture(self.texture.clone()); @@ -110,7 +110,7 @@ pub struct SetColorModifier { impl_mod_render!(SetColorModifier, &[]); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for SetColorModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { context.vertex_code += &format!("color = {0};\n", self.color.to_wgsl_string()); @@ -144,7 +144,7 @@ impl_mod_render!( &[Attribute::AGE, Attribute::LIFETIME] ); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for ColorOverLifetimeModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { let func_name = context.add_color_gradient(self.gradient.clone()); @@ -195,7 +195,7 @@ pub struct SetSizeModifier { impl_mod_render!(SetSizeModifier, &[]); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for SetSizeModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { context.vertex_code += &format!("size = {0};\n", self.size.to_wgsl_string()); @@ -233,7 +233,7 @@ impl_mod_render!( &[Attribute::AGE, Attribute::LIFETIME] ); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for SizeOverLifetimeModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { let func_name = context.add_size_gradient(self.gradient.clone()); @@ -360,7 +360,7 @@ impl OrientModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for OrientModifier { fn context(&self) -> ModifierContext { ModifierContext::Render @@ -394,7 +394,7 @@ impl Modifier for OrientModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for OrientModifier { fn apply_render(&self, module: &mut Module, context: &mut RenderContext) { match self.mode { @@ -559,7 +559,7 @@ impl Default for FlipbookModifier { impl_mod_render!(FlipbookModifier, &[Attribute::SPRITE_INDEX]); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for FlipbookModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { context.sprite_grid_size = Some(self.sprite_grid_size); @@ -602,7 +602,7 @@ impl_mod_render!( &[Attribute::POSITION, Attribute::SIZE] ); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for ScreenSpaceSizeModifier { fn apply_render(&self, _module: &mut Module, context: &mut RenderContext) { // Get perspective divide factor from clip space position. This is the "average" @@ -659,7 +659,7 @@ pub struct RoundModifier { impl_mod_render!(RoundModifier, &[]); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for RoundModifier { fn apply_render(&self, module: &mut Module, context: &mut RenderContext) { context.set_needs_uv(); diff --git a/src/modifier/position.rs b/src/modifier/position.rs index c548181a..9c8763ca 100644 --- a/src/modifier/position.rs +++ b/src/modifier/position.rs @@ -108,7 +108,7 @@ impl SetPositionCircleModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetPositionCircleModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update @@ -211,7 +211,7 @@ impl SetPositionSphereModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetPositionSphereModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update @@ -326,7 +326,7 @@ impl SetPositionCone3dModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetPositionCone3dModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update diff --git a/src/modifier/ribbon.rs b/src/modifier/ribbon.rs index a64440e9..253d850d 100644 --- a/src/modifier/ribbon.rs +++ b/src/modifier/ribbon.rs @@ -18,7 +18,7 @@ pub struct RibbonModifier; impl_mod_render!(RibbonModifier, &[Attribute::PREV, Attribute::NEXT]); -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl RenderModifier for RibbonModifier { fn apply_render(&self, _: &mut Module, context: &mut RenderContext) { context.vertex_code += r##" diff --git a/src/modifier/velocity.rs b/src/modifier/velocity.rs index de0d3173..234fb333 100644 --- a/src/modifier/velocity.rs +++ b/src/modifier/velocity.rs @@ -80,7 +80,7 @@ impl SetVelocityCircleModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetVelocityCircleModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update @@ -140,7 +140,7 @@ impl SetVelocitySphereModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetVelocitySphereModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update @@ -225,7 +225,7 @@ impl SetVelocityTangentModifier { } } -#[typetag::serde] +#[cfg_attr(feature = "serde", typetag::serde)] impl Modifier for SetVelocityTangentModifier { fn context(&self) -> ModifierContext { ModifierContext::Init | ModifierContext::Update diff --git a/src/plugin.rs b/src/plugin.rs index fa7dd76e..f87ccda3 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -16,7 +16,7 @@ use bevy::{ }; use crate::{ - asset::{EffectAsset, EffectAssetLoader}, + asset::EffectAsset, compile_effects, gather_removed_effects, properties::EffectProperties, render::{ @@ -34,6 +34,9 @@ use crate::{ RemovedEffectsEvent, Spawner, }; +#[cfg(feature = "serde")] +use crate::asset::EffectAssetLoader; + /// Labels for the Hanabi systems. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SystemSet)] pub enum EffectSystems { @@ -179,7 +182,6 @@ impl Plugin for HanabiPlugin { .add_event::() .insert_resource(Random(spawn::new_rng())) .init_resource::() - .init_asset_loader::() .init_resource::>() .configure_sets( PostUpdate, @@ -214,6 +216,9 @@ impl Plugin for HanabiPlugin { ), ); + #[cfg(feature = "serde")] + app.init_asset_loader::(); + // Register types with reflection app.register_type::() .register_type::()