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>,
|
properties: Vec<PropertyDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PropertyAndDefault {
|
||||||
|
name: Ident,
|
||||||
|
default: Ident,
|
||||||
|
}
|
||||||
struct BlockDefinition {
|
struct BlockDefinition {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
behavior: Expr,
|
behavior: Expr,
|
||||||
properties: Punctuated<Ident, Token![,]>,
|
properties_and_defaults: Vec<PropertyAndDefault>,
|
||||||
}
|
}
|
||||||
struct BlockDefinitions {
|
struct BlockDefinitions {
|
||||||
blocks: Vec<BlockDefinition>,
|
blocks: Vec<BlockDefinition>,
|
||||||
|
@ -39,14 +43,14 @@ impl Parse for PropertyDefinition {
|
||||||
// Floor,
|
// Floor,
|
||||||
// Wall,
|
// Wall,
|
||||||
// Ceiling
|
// Ceiling
|
||||||
// };
|
// },
|
||||||
let name = input.parse()?;
|
let name = input.parse()?;
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
braced!(content in input);
|
braced!(content in input);
|
||||||
let variants = content.parse_terminated(Ident::parse)?;
|
let variants = content.parse_terminated(Ident::parse)?;
|
||||||
|
|
||||||
input.parse::<Token![;]>()?;
|
input.parse::<Token![,]>()?;
|
||||||
Ok(PropertyDefinition { name, variants })
|
Ok(PropertyDefinition { name, variants })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,11 +70,11 @@ impl Parse for PropertyDefinitions {
|
||||||
|
|
||||||
impl Parse for BlockDefinition {
|
impl Parse for BlockDefinition {
|
||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
// acacia_button => BlockBehavior { has_collision: false }, {
|
// acacia_button => BlockBehavior::default().no_collision(), {
|
||||||
// Face,
|
// Face,
|
||||||
// Facing,
|
// Facing,
|
||||||
// Powered
|
// Powered
|
||||||
// };
|
// },
|
||||||
let name = input.parse()?;
|
let name = input.parse()?;
|
||||||
input.parse::<Token![=>]>()?;
|
input.parse::<Token![=>]>()?;
|
||||||
let behavior = input.parse()?;
|
let behavior = input.parse()?;
|
||||||
|
@ -78,12 +82,29 @@ impl Parse for BlockDefinition {
|
||||||
input.parse::<Token![,]>()?;
|
input.parse::<Token![,]>()?;
|
||||||
let content;
|
let content;
|
||||||
braced!(content in input);
|
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 {
|
Ok(BlockDefinition {
|
||||||
name,
|
name,
|
||||||
behavior,
|
behavior,
|
||||||
properties,
|
properties_and_defaults,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +130,8 @@ impl Parse for MakeBlockStates {
|
||||||
braced!(content in input);
|
braced!(content in input);
|
||||||
let properties = content.parse()?;
|
let properties = content.parse()?;
|
||||||
|
|
||||||
|
input.parse::<Token![,]>()?;
|
||||||
|
|
||||||
let blocks_ident = input.parse::<Ident>()?;
|
let blocks_ident = input.parse::<Ident>()?;
|
||||||
assert_eq!(blocks_ident.to_string(), "Blocks");
|
assert_eq!(blocks_ident.to_string(), "Blocks");
|
||||||
input.parse::<Token![=>]>()?;
|
input.parse::<Token![=>]>()?;
|
||||||
|
@ -183,9 +206,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
|
||||||
let mut from_state_to_block_match = quote! {};
|
let mut from_state_to_block_match = quote! {};
|
||||||
for block in &input.block_definitions.blocks {
|
for block in &input.block_definitions.blocks {
|
||||||
let block_property_names = &block
|
let block_property_names = &block
|
||||||
.properties
|
.properties_and_defaults
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.to_string())
|
.map(|p| p.name.to_string())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let mut block_properties_vec = Vec::new();
|
let mut block_properties_vec = Vec::new();
|
||||||
for property_name in block_property_names {
|
for property_name in block_property_names {
|
||||||
|
@ -200,7 +223,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
|
||||||
// pub facing: properties::Facing,
|
// pub facing: properties::Facing,
|
||||||
// pub powered: properties::Powered,
|
// pub powered: properties::Powered,
|
||||||
let mut block_struct_fields = quote! {};
|
let mut block_struct_fields = quote! {};
|
||||||
for property in &block.properties {
|
for PropertyAndDefault { name: property, .. } in &block.properties_and_defaults {
|
||||||
let property_name_snake =
|
let property_name_snake =
|
||||||
Ident::new(&property.to_string(), proc_macro2::Span::call_site());
|
Ident::new(&property.to_string(), proc_macro2::Span::call_site());
|
||||||
block_struct_fields.extend(quote! {
|
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 from_state_to_block_inner = quote! {};
|
||||||
let mut division = 1usize;
|
let mut division = 1usize;
|
||||||
for i in (0..block.properties.len()).rev() {
|
for i in (0..block.properties_and_defaults.len()).rev() {
|
||||||
let property = &block.properties[i];
|
let PropertyAndDefault {
|
||||||
|
name: property_name,
|
||||||
|
..
|
||||||
|
} = &block.properties_and_defaults[i];
|
||||||
|
|
||||||
let property_variants = &block_properties_vec[i];
|
let property_variants = &block_properties_vec[i];
|
||||||
let property_variants_count = property_variants.len();
|
let property_variants_count = property_variants.len();
|
||||||
from_state_to_block_inner.extend(quote! {
|
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;
|
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_behavior = &block.behavior;
|
||||||
let block_id = block.name.to_string();
|
let block_id = block.name.to_string();
|
||||||
let block_struct = quote! {
|
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);
|
block_structs.extend(block_struct);
|
||||||
|
|
|
@ -12,43 +12,43 @@ make_block_states! {
|
||||||
Floor,
|
Floor,
|
||||||
Wall,
|
Wall,
|
||||||
Ceiling
|
Ceiling
|
||||||
};
|
},
|
||||||
Facing {
|
Facing {
|
||||||
North,
|
North,
|
||||||
South,
|
South,
|
||||||
West,
|
West,
|
||||||
East
|
East
|
||||||
};
|
},
|
||||||
Powered {
|
Powered {
|
||||||
True,
|
True,
|
||||||
False
|
False
|
||||||
};
|
},
|
||||||
Half {
|
Half {
|
||||||
Upper,
|
Upper,
|
||||||
Lower
|
Lower
|
||||||
};
|
},
|
||||||
Hinge {
|
Hinge {
|
||||||
Left,
|
Left,
|
||||||
Right
|
Right
|
||||||
};
|
},
|
||||||
Open {
|
Open {
|
||||||
True,
|
True,
|
||||||
False
|
False
|
||||||
};
|
},
|
||||||
}
|
},
|
||||||
Blocks => {
|
Blocks => {
|
||||||
acacia_button => BlockBehavior::default().no_collision(), {
|
acacia_button => BlockBehavior::default().no_collision(), {
|
||||||
Face,
|
Face=Floor,
|
||||||
Facing,
|
Facing=North,
|
||||||
Powered
|
Powered=True
|
||||||
};
|
},
|
||||||
acacia_door => BlockBehavior::default(), {
|
acacia_door => BlockBehavior::default(), {
|
||||||
Facing,
|
Facing=North,
|
||||||
Half,
|
Half=Upper,
|
||||||
Hinge,
|
Hinge=Left,
|
||||||
Open,
|
Open=True,
|
||||||
Powered
|
Powered=True
|
||||||
};
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
from lib.utils import to_camel_case
|
||||||
from lib.utils import get_dir_location
|
from lib.utils import get_dir_location
|
||||||
|
import json
|
||||||
|
|
||||||
BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/blocks.rs')
|
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 = []
|
||||||
new_make_block_states_macro_code.append('make_block_states! {')
|
new_make_block_states_macro_code.append('make_block_states! {')
|
||||||
|
|
||||||
|
# Find properties
|
||||||
properties = {}
|
properties = {}
|
||||||
for block_name, block_data in blocks.items():
|
for block_data in blocks.values():
|
||||||
block_properties = block_data['properties']
|
block_properties = block_data.get('properties', {})
|
||||||
|
|
||||||
properties.update(block_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):
|
def to_camel_case(name: str):
|
||||||
s = re.sub('_([a-z])', lambda m: m.group(1).upper(), name)
|
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):
|
def padded_hex(n: int):
|
||||||
|
|
Loading…
Reference in a new issue