From f003127901c9bb724e8c4f079e54861c1f667ff5 Mon Sep 17 00:00:00 2001 From: lena <77104725+elenakrittik@users.noreply.github.com> Date: Mon, 18 Sep 2023 04:39:42 +0300 Subject: [PATCH] feat!: use the bundle's `Default` implementation rather than the field's in `LdtkEntity` and `LdtkIntCell` derive macros (#222) Changes the default behavior to use bundle's struct's `Default` `impl` instead of each individual's field. Solves #119. - [x] I have properly formatted code using `cargo fmt`. - [x] I have tested the code and documentation i changed by both crafting and running an example and by running `cargo test`. - [x] I have ran `cargo clippy` and fixed any issues arising from my changes. --- README.md | 2 +- examples/basic.rs | 2 +- macros/src/ldtk_entity.rs | 13 ++++++++----- macros/src/ldtk_int_cell.rs | 13 ++++++++----- macros/src/lib.rs | 4 ++-- src/app/entity_app_ext.rs | 2 +- src/app/int_cell_app_ext.rs | 2 +- src/app/ldtk_entity.rs | 25 +++++++++++++------------ src/app/ldtk_int_cell.rs | 15 ++++++++------- src/lib.rs | 2 +- 10 files changed, 44 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 600e95bc..38e3f375 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }); } -#[derive(Bundle, LdtkEntity)] +#[derive(Default, Bundle, LdtkEntity)] pub struct MyBundle { a: ComponentA, b: ComponentB, diff --git a/examples/basic.rs b/examples/basic.rs index e7d3dc59..7e3e1ffa 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -28,7 +28,7 @@ struct ComponentA; #[derive(Default, Component)] struct ComponentB; -#[derive(Bundle, LdtkEntity)] +#[derive(Default, Bundle, LdtkEntity)] pub struct MyBundle { a: ComponentA, b: ComponentB, diff --git a/macros/src/ldtk_entity.rs b/macros/src/ldtk_entity.rs index 787593c2..75dd55e0 100644 --- a/macros/src/ldtk_entity.rs +++ b/macros/src/ldtk_entity.rs @@ -8,7 +8,7 @@ static LDTK_ENTITY_ATTRIBUTE_NAME: &str = "ldtk_entity"; static FROM_ENTITY_INSTANCE_ATTRIBUTE_NAME: &str = "from_entity_instance"; static WITH_ATTRIBUTE_NAME: &str = "with"; -pub fn expand_ldtk_entity_derive(ast: &syn::DeriveInput) -> proc_macro::TokenStream { +pub fn expand_ldtk_entity_derive(ast: syn::DeriveInput) -> proc_macro::TokenStream { let struct_name = &ast.ident; let fields = match &ast.data { @@ -96,15 +96,17 @@ pub fn expand_ldtk_entity_derive(ast: &syn::DeriveInput) -> proc_macro::TokenStr field_constructions.push(expand_with_attribute(attribute, field_name, field_type)); continue; } - - field_constructions.push(quote! { - #field_name: <#field_type as std::default::Default>::default(), - }); } let generics = &ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let struct_update = if field_constructions.len() < fields.len() { + quote! { ..::default() } + } else { + quote! {} + }; + let gen = quote! { impl #impl_generics bevy_ecs_ldtk::prelude::LdtkEntity for #struct_name #ty_generics #where_clause { fn bundle_entity( @@ -117,6 +119,7 @@ pub fn expand_ldtk_entity_derive(ast: &syn::DeriveInput) -> proc_macro::TokenStr ) -> Self { Self { #(#field_constructions)* + #struct_update } } } diff --git a/macros/src/ldtk_int_cell.rs b/macros/src/ldtk_int_cell.rs index 21e893dd..f0d7250c 100644 --- a/macros/src/ldtk_int_cell.rs +++ b/macros/src/ldtk_int_cell.rs @@ -4,7 +4,7 @@ static LDTK_INT_CELL_ATTRIBUTE_NAME: &str = "ldtk_int_cell"; static FROM_INT_GRID_CELL_ATTRIBUTE_NAME: &str = "from_int_grid_cell"; static WITH_ATTRIBUTE_NAME: &str = "with"; -pub fn expand_ldtk_int_cell_derive(ast: &syn::DeriveInput) -> proc_macro::TokenStream { +pub fn expand_ldtk_int_cell_derive(ast: syn::DeriveInput) -> proc_macro::TokenStream { let struct_name = &ast.ident; let fields = match &ast.data { @@ -50,15 +50,17 @@ pub fn expand_ldtk_int_cell_derive(ast: &syn::DeriveInput) -> proc_macro::TokenS field_constructions.push(expand_with_attribute(attribute, field_name, field_type)); continue; } - - field_constructions.push(quote! { - #field_name: <#field_type as std::default::Default>::default(), - }); } let generics = &ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let struct_update = if field_constructions.len() < fields.len() { + quote! { ..::default() } + } else { + quote! {} + }; + let gen = quote! { impl #impl_generics bevy_ecs_ldtk::prelude::LdtkIntCell for #struct_name #ty_generics #where_clause { fn bundle_int_cell( @@ -67,6 +69,7 @@ pub fn expand_ldtk_int_cell_derive(ast: &syn::DeriveInput) -> proc_macro::TokenS ) -> Self { Self { #(#field_constructions)* + #struct_update } } } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index af99cd37..a23d295b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -18,12 +18,12 @@ mod ldtk_int_cell; pub fn ldtk_entity_derive(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); - ldtk_entity::expand_ldtk_entity_derive(&ast) + ldtk_entity::expand_ldtk_entity_derive(ast) } #[proc_macro_derive(LdtkIntCell, attributes(ldtk_int_cell, from_int_grid_cell, with))] pub fn ldtk_int_cell_derive(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); - ldtk_int_cell::expand_ldtk_int_cell_derive(&ast) + ldtk_int_cell::expand_ldtk_int_cell_derive(ast) } diff --git a/src/app/entity_app_ext.rs b/src/app/entity_app_ext.rs index 5ee425dc..98b92d42 100644 --- a/src/app/entity_app_ext.rs +++ b/src/app/entity_app_ext.rs @@ -56,7 +56,7 @@ pub trait LdtkEntityAppExt { /// # struct ComponentB; /// # #[derive(Component, Default)] /// # struct ComponentC; - /// #[derive(Bundle, LdtkEntity)] + /// #[derive(Bundle, LdtkEntity, Default)] /// pub struct MyBundle { /// a: ComponentA, /// b: ComponentB, diff --git a/src/app/int_cell_app_ext.rs b/src/app/int_cell_app_ext.rs index 6efe7e14..43a1e00f 100644 --- a/src/app/int_cell_app_ext.rs +++ b/src/app/int_cell_app_ext.rs @@ -56,7 +56,7 @@ pub trait LdtkIntCellAppExt { /// # struct ComponentB; /// # #[derive(Component, Default)] /// # struct ComponentC; - /// #[derive(Bundle, LdtkIntCell)] + /// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct MyBundle { /// a: ComponentA, /// b: ComponentB, diff --git a/src/app/ldtk_entity.rs b/src/app/ldtk_entity.rs index 90d1e91b..aac4ce13 100644 --- a/src/app/ldtk_entity.rs +++ b/src/app/ldtk_entity.rs @@ -50,7 +50,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct ComponentB; /// # #[derive(Component, Default)] /// # struct ComponentC; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct MyBundle { /// a: ComponentA, /// b: ComponentB, @@ -60,8 +60,9 @@ use std::{collections::HashMap, marker::PhantomData}; /// Now, when loading your ldtk file, any entities with the entity identifier /// "my_entity_identifier" will be spawned as `MyBundle`s. /// -/// By default, each component or nested bundle in the bundle will be created using their [Default] -/// implementations. +/// By default, each component or nested bundle in the bundle will be consumed from bundle's +/// [Default] implementation, which means that deriving (or implementing manually) [Default] +/// is required (unless all fields are overriden, see below). /// However, this behavior can be overridden with some field attribute macros... /// /// ### `#[sprite_bundle...]` @@ -80,14 +81,14 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct PlayerComponent; /// # #[derive(Component, Default)] /// # struct Health; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Gem { /// #[sprite_bundle("textures/gem.png")] /// sprite_bundle: SpriteBundle, /// sellable: Sellable, /// } /// -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Player { /// player: PlayerComponent, /// health: Health, @@ -116,14 +117,14 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct Damage; /// # #[derive(Component, Default)] /// # struct BleedDamage; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Sword { /// #[sprite_sheet_bundle("weapons.png", 32.0, 32.0, 4, 5, 5.0, 1.0, 17)] /// sprite_sheet: SpriteSheetBundle, /// damage: Damage, /// } /// -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Dagger { /// damage: Damage, /// bleed_damage: BleedDamage, @@ -145,7 +146,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct Player; /// # #[derive(Component, Default)] /// # struct BleedDamage; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct PlayerBundle { /// player: Player, /// #[sprite_sheet_bundle] @@ -167,7 +168,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct Block; /// # #[derive(Component, Default)] /// # struct Movable; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct BlockBundle { /// block: Block, /// movable: Movable, @@ -192,14 +193,14 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct Damage; /// # #[derive(Component, Default)] /// # struct BleedDamage; -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Weapon { /// damage: Damage, /// #[sprite_bundle] /// sprite: SpriteBundle, /// } /// -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct Dagger { /// #[ldtk_entity] /// weapon_bundle: Weapon, @@ -234,7 +235,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// } /// } /// -/// #[derive(Bundle, LdtkEntity)] +/// #[derive(Bundle, LdtkEntity, Default)] /// pub struct NickelBundle { /// #[sprite_bundle] /// sprite: SpriteBundle, diff --git a/src/app/ldtk_int_cell.rs b/src/app/ldtk_int_cell.rs index 7c345929..a32095a2 100644 --- a/src/app/ldtk_int_cell.rs +++ b/src/app/ldtk_int_cell.rs @@ -46,7 +46,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct ComponentB; /// # #[derive(Component, Default)] /// # struct ComponentC; -/// #[derive(Bundle, LdtkIntCell)] +/// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct MyBundle { /// a: ComponentA, /// b: ComponentB, @@ -56,8 +56,9 @@ use std::{collections::HashMap, marker::PhantomData}; /// Now, when loading your ldtk file, any IntGrid tiles with the value `1` will be spawned with as /// tiles with `MyBundle` inserted. /// -/// By default, each component or nested bundle in the bundle will be created using their [Default] -/// implementations. +/// By default, each component or nested bundle in the bundle will be consumed from bundle's +/// [Default] implementation, which means that deriving (or implementing manually) [Default] +/// is required (unless all fields are overriden, see below). /// However, this behavior can be overriden with some field attribute macros... /// /// ### `#[ldtk_int_cell]` @@ -74,12 +75,12 @@ use std::{collections::HashMap, marker::PhantomData}; /// # struct RigidBody; /// # #[derive(Component, Default)] /// # struct Damage; -/// #[derive(Bundle, LdtkIntCell)] +/// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct Wall { /// rigid_body: RigidBody, /// } /// -/// #[derive(Bundle, LdtkIntCell)] +/// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct DestructibleWall { /// #[ldtk_int_cell] /// wall: Wall, @@ -115,7 +116,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// } /// } /// -/// #[derive(Bundle, LdtkIntCell)] +/// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct Lava { /// #[from_int_grid_cell] /// fluid: Fluid, @@ -146,7 +147,7 @@ use std::{collections::HashMap, marker::PhantomData}; /// } /// } /// -/// #[derive(Bundle, LdtkIntCell)] +/// #[derive(Bundle, LdtkIntCell, Default)] /// pub struct Lava { /// #[with(initial_fluid)] /// fluid: Fluid, diff --git a/src/lib.rs b/src/lib.rs index b6cd5d51..f2e3054e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ //! # #[derive(Default, Component)] //! # struct ComponentB; //! # -//! #[derive(Bundle, LdtkEntity)] +//! #[derive(Default, Bundle, LdtkEntity)] //! pub struct MyBundle { //! a: ComponentA, //! b: ComponentB,