aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-28 20:59:22 -0500
committermat <github@matdoes.dev>2022-05-28 20:59:22 -0500
commit9c1c2862361a4863cfd0af36c80705fb6213c3a4 (patch)
treeaafbc0089624da25c530abdfa8e8435cb12f9347
parent8cd0ff2aac9f8a03446f897c48fc92b00b5291a2 (diff)
downloadazalea-drasl-9c1c2862361a4863cfd0af36c80705fb6213c3a4.tar.xz
default block properties
-rw-r--r--azalea-block/block-macros/src/lib.rs73
-rw-r--r--azalea-block/src/blocks.rs34
-rw-r--r--codegen/lib/code/blocks.py46
-rw-r--r--codegen/lib/utils.py7
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):