diff options
| author | mat <github@matdoes.dev> | 2022-05-28 20:59:22 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-05-28 20:59:22 -0500 |
| commit | 9c1c2862361a4863cfd0af36c80705fb6213c3a4 (patch) | |
| tree | aafbc0089624da25c530abdfa8e8435cb12f9347 | |
| parent | 8cd0ff2aac9f8a03446f897c48fc92b00b5291a2 (diff) | |
| download | azalea-drasl-9c1c2862361a4863cfd0af36c80705fb6213c3a4.tar.xz | |
default block properties
| -rw-r--r-- | azalea-block/block-macros/src/lib.rs | 73 | ||||
| -rw-r--r-- | azalea-block/src/blocks.rs | 34 | ||||
| -rw-r--r-- | codegen/lib/code/blocks.py | 46 | ||||
| -rw-r--r-- | codegen/lib/utils.py | 7 |
4 files changed, 123 insertions, 37 deletions
diff --git a/azalea-block/block-macros/src/lib.rs b/azalea-block/block-macros/src/lib.rs index 63e21e58..c0b5422d 100644 --- a/azalea-block/block-macros/src/lib.rs +++ b/azalea-block/block-macros/src/lib.rs @@ -20,10 +20,14 @@ struct PropertyDefinitions { properties: Vec<PropertyDefinition>, } +struct PropertyAndDefault { + name: Ident, + default: Ident, +} struct BlockDefinition { name: Ident, behavior: Expr, - properties: Punctuated<Ident, Token![,]>, + properties_and_defaults: Vec<PropertyAndDefault>, } struct BlockDefinitions { blocks: Vec<BlockDefinition>, @@ -39,14 +43,14 @@ impl Parse for PropertyDefinition { // Floor, // Wall, // Ceiling - // }; + // }, let name = input.parse()?; let content; braced!(content in input); let variants = content.parse_terminated(Ident::parse)?; - input.parse::<Token![;]>()?; + input.parse::<Token![,]>()?; Ok(PropertyDefinition { name, variants }) } } @@ -66,11 +70,11 @@ impl Parse for PropertyDefinitions { impl Parse for BlockDefinition { fn parse(input: ParseStream) -> Result<Self> { - // acacia_button => BlockBehavior { has_collision: false }, { + // acacia_button => BlockBehavior::default().no_collision(), { // Face, // Facing, // Powered - // }; + // }, let name = input.parse()?; input.parse::<Token![=>]>()?; let behavior = input.parse()?; @@ -78,12 +82,29 @@ impl Parse for BlockDefinition { input.parse::<Token![,]>()?; let content; braced!(content in input); - let properties = content.parse_terminated(Ident::parse)?; - input.parse::<Token![;]>()?; + + let mut properties_and_defaults = Vec::new(); + + loop { + let property = match content.parse() { + Ok(property) => property, + Err(_) => break, + }; + content.parse::<Token![=]>()?; + let property_default = content.parse()?; + properties_and_defaults.push(PropertyAndDefault { + name: property, + default: property_default, + }); + if content.parse::<Token![,]>().is_err() { + break; + } + } + input.parse::<Token![,]>()?; Ok(BlockDefinition { name, behavior, - properties, + properties_and_defaults, }) } } @@ -109,6 +130,8 @@ impl Parse for MakeBlockStates { braced!(content in input); let properties = content.parse()?; + input.parse::<Token![,]>()?; + let blocks_ident = input.parse::<Ident>()?; assert_eq!(blocks_ident.to_string(), "Blocks"); input.parse::<Token![=>]>()?; @@ -183,9 +206,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { let mut from_state_to_block_match = quote! {}; for block in &input.block_definitions.blocks { let block_property_names = &block - .properties + .properties_and_defaults .iter() - .map(|p| p.to_string()) + .map(|p| p.name.to_string()) .collect::<Vec<_>>(); let mut block_properties_vec = Vec::new(); for property_name in block_property_names { @@ -200,7 +223,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { // pub facing: properties::Facing, // pub powered: properties::Powered, let mut block_struct_fields = quote! {}; - for property in &block.properties { + for PropertyAndDefault { name: property, .. } in &block.properties_and_defaults { let property_name_snake = Ident::new(&property.to_string(), proc_macro2::Span::call_site()); block_struct_fields.extend(quote! { @@ -268,12 +291,16 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { // } let mut from_state_to_block_inner = quote! {}; let mut division = 1usize; - for i in (0..block.properties.len()).rev() { - let property = &block.properties[i]; + for i in (0..block.properties_and_defaults.len()).rev() { + let PropertyAndDefault { + name: property_name, + .. + } = &block.properties_and_defaults[i]; + let property_variants = &block_properties_vec[i]; let property_variants_count = property_variants.len(); from_state_to_block_inner.extend(quote! { - #property: #property::from((b / #division) % #property_variants_count), + #property_name: #property_name::from((b / #division) % #property_variants_count), }); division *= property_variants_count; @@ -289,6 +316,17 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { }, }); + let mut block_default_fields = quote! {}; + for PropertyAndDefault { + name: property, + default: property_default, + } in &block.properties_and_defaults + { + block_default_fields.extend(quote! { + #property: #property::#property_default, + }) + } + let block_behavior = &block.behavior; let block_id = block.name.to_string(); let block_struct = quote! { @@ -314,6 +352,13 @@ pub fn make_block_states(input: TokenStream) -> TokenStream { } } + impl Default for #block_struct_name { + fn default() -> Self { + Self { + #block_default_fields + } + } + } }; block_structs.extend(block_struct); diff --git a/azalea-block/src/blocks.rs b/azalea-block/src/blocks.rs index 88253e34..8a4a150b 100644 --- a/azalea-block/src/blocks.rs +++ b/azalea-block/src/blocks.rs @@ -12,43 +12,43 @@ make_block_states! { Floor, Wall, Ceiling - }; + }, Facing { North, South, West, East - }; + }, Powered { True, False - }; + }, Half { Upper, Lower - }; + }, Hinge { Left, Right - }; + }, Open { True, False - }; - } + }, + }, Blocks => { acacia_button => BlockBehavior::default().no_collision(), { - Face, - Facing, - Powered - }; + Face=Floor, + Facing=North, + Powered=True + }, acacia_door => BlockBehavior::default(), { - Facing, - Half, - Hinge, - Open, - Powered - }; + Facing=North, + Half=Upper, + Hinge=Left, + Open=True, + Powered=True + }, } } diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py index fd268b98..a8f9afd1 100644 --- a/codegen/lib/code/blocks.py +++ b/codegen/lib/code/blocks.py @@ -1,5 +1,6 @@ +from lib.utils import to_camel_case from lib.utils import get_dir_location - +import json BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/blocks.rs') @@ -11,10 +12,45 @@ def generate_blocks(blocks: dict): new_make_block_states_macro_code = [] new_make_block_states_macro_code.append('make_block_states! {') + # Find properties properties = {} - for block_name, block_data in blocks.items(): - block_properties = block_data['properties'] - + for block_data in blocks.values(): + block_properties = block_data.get('properties', {}) properties.update(block_properties) - print(properties) + # Property codegen + new_make_block_states_macro_code.append(' Properties => {') + for property_name, property_variants in properties.items(): + new_make_block_states_macro_code.append( + f' {to_camel_case(property_name)} => {{') + + for variant in property_variants: + new_make_block_states_macro_code.append( + f' {to_camel_case(variant)},') + + new_make_block_states_macro_code.append( + f' }},') + new_make_block_states_macro_code.append(' },') + + # Block codegen + new_make_block_states_macro_code.append(' Blocks => {') + for block_id, block_data in blocks.items(): + block_id = block_id.split(':')[1] + block_states = block_data['states'] + + default_property_variants = {} + for state in block_states: + if state.get('default'): + default_property_variants = state.get('properties', {}) + + # TODO: use burger to generate the blockbehavior + new_make_block_states_macro_code.append( + f' {block_id} => BlockBehavior::default(), {{') + for property in block_data.get('properties', {}): + property_default = default_property_variants.get(property) + new_make_block_states_macro_code.append( + f' {to_camel_case(property)}={to_camel_case(property_default)},') + new_make_block_states_macro_code.append(' },') + new_make_block_states_macro_code.append(' },') + + print('\n'.join(new_make_block_states_macro_code)) diff --git a/codegen/lib/utils.py b/codegen/lib/utils.py index 77a7b2d4..fb43af21 100644 --- a/codegen/lib/utils.py +++ b/codegen/lib/utils.py @@ -11,7 +11,12 @@ def to_snake_case(name: str): def to_camel_case(name: str): s = re.sub('_([a-z])', lambda m: m.group(1).upper(), name) - return s[0].upper() + s[1:] + s = s[0].upper() + s[1:] + # if the first character is a number, we need to add an underscore + # maybe we could convert it to the number name (like 2 would become "two")? + if s[0].isdigit(): + s = f'_{s}' + return s def padded_hex(n: int): |
