mirror of
https://github.com/mat-1/azalea.git
synced 2024-09-19 22:52:32 +00:00
default block properties
This commit is contained in:
parent
8cd0ff2aac
commit
9c1c286236
4 changed files with 123 additions and 37 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue