From 3573eb4ba04280cd25263fbe6e468b05036bc9cb Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 28 May 2022 01:12:12 -0500 Subject: [PATCH] more block macro stuff --- azalea-block/block-macros/src/lib.rs | 79 ++++++++++++++++++++++++++-- azalea-block/src/behavior.rs | 9 ++++ azalea-block/src/blocks.rs | 9 +++- azalea-block/src/lib.rs | 7 ++- 4 files changed, 97 insertions(+), 7 deletions(-) diff --git a/azalea-block/block-macros/src/lib.rs b/azalea-block/block-macros/src/lib.rs index 9cbd6ca3..0ad5af34 100644 --- a/azalea-block/block-macros/src/lib.rs +++ b/azalea-block/block-macros/src/lib.rs @@ -152,17 +152,40 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { } let mut block_state_enum_variants = quote! {}; + let mut block_structs = quote! {}; for block in &input.block_definitions.blocks { - let block_properties = &block.properties; + let block_property_names = &block + .properties + .iter() + .map(|p| p.to_string()) + .collect::>(); let mut block_properties_vec = Vec::new(); - for property in block_properties { - let property_name = &property.to_string(); + for property_name in block_property_names { let property_variants = properties_map .get(property_name) .expect(format!("Property '{}' not found", property_name).as_str()) .clone(); block_properties_vec.push(property_variants); } + + // pub face: properties::Face, + // pub facing: properties::Facing, + // pub powered: properties::Powered, + let mut block_struct_fields = quote! {}; + for property in &block.properties { + let property_name_snake = + Ident::new(&property.to_string(), proc_macro2::Span::call_site()); + block_struct_fields.extend(quote! { + pub #property_name_snake: #property, + }) + } + let block_struct_name = Ident::new( + &format!("{}Block", to_pascal_case(&block.name.to_string())), + proc_macro2::Span::call_site(), + ); + + let mut from_block_to_state_match = quote! {}; + for combination in combinations_of(&block_properties_vec) { let variant_name = Ident::new( &format!( @@ -179,7 +202,55 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { block_state_enum_variants.extend(quote! { #variant_name, }); + + // face: properties::Face::Floor, + // facing: properties::Facing::North, + // powered: properties::Powered::True, + let mut from_block_to_state_match_inner = quote! {}; + for i in 0..block_property_names.len() { + let property_name = &block_property_names[i]; + let property_name_ident = Ident::new(property_name, proc_macro2::Span::call_site()); + let property_name_snake = + Ident::new(&property_name.to_string(), proc_macro2::Span::call_site()); + let variant = + Ident::new(&combination[i].to_string(), proc_macro2::Span::call_site()); + + from_block_to_state_match_inner.extend(quote! { + #property_name_ident: #property_name_snake::#variant, + }); + } + + from_block_to_state_match.extend(quote! { + #block_struct_name { + #from_block_to_state_match_inner + } => BlockState::#variant_name, + }); } + + let block_behavior = &block.behavior; + let block_struct = quote! { + #[derive(Debug)] + pub struct #block_struct_name { + #block_struct_fields + } + + impl Block for #block_struct_name { + fn behavior(&self) -> BlockBehavior { + #block_behavior + } + } + + impl From<#block_struct_name> for BlockState { + fn from(b: #block_struct_name) -> Self { + match b { + #from_block_to_state_match + } + } + } + + }; + + block_structs.extend(block_struct); } quote! { @@ -188,6 +259,8 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { pub enum BlockState { #block_state_enum_variants } + + #block_structs } .into() } diff --git a/azalea-block/src/behavior.rs b/azalea-block/src/behavior.rs index 974260f2..949f3bd8 100644 --- a/azalea-block/src/behavior.rs +++ b/azalea-block/src/behavior.rs @@ -1,3 +1,12 @@ +#[derive(Default)] pub struct BlockBehavior { pub has_collision: bool, } + +impl BlockBehavior { + #[inline] + pub fn no_collision(mut self) -> Self { + self.has_collision = false; + self + } +} diff --git a/azalea-block/src/blocks.rs b/azalea-block/src/blocks.rs index 855de96b..d4339ada 100644 --- a/azalea-block/src/blocks.rs +++ b/azalea-block/src/blocks.rs @@ -1,5 +1,10 @@ +use crate::BlockBehavior; use block_macros::make_block_states; +pub trait Block { + fn behavior(&self) -> BlockBehavior; +} + make_block_states! { PROPERTIES => { Face { @@ -31,12 +36,12 @@ make_block_states! { }; } BLOCKS => { - acacia_button => BlockBehavior::new().no_collision(), { + acacia_button => BlockBehavior::default().no_collision(), { Face, Facing, Powered }; - acacia_door => BlockBehavior::new(), { + acacia_door => BlockBehavior::default(), { Facing, Half, Hinge, diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index 488e8e62..459b486e 100644 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -1,2 +1,5 @@ -pub mod behavior; -pub mod blocks; +mod behavior; +mod blocks; + +pub use behavior::BlockBehavior; +pub use blocks::*;