Start making block macro

This commit is contained in:
mat 2022-05-27 19:34:09 -05:00
parent aac64d0135
commit 88bc6d1660
7 changed files with 310 additions and 116 deletions

40
Cargo.lock generated
View file

@ -81,6 +81,9 @@ dependencies = [
[[package]] [[package]]
name = "azalea-block" name = "azalea-block"
version = "0.1.0" version = "0.1.0"
dependencies = [
"block-macros",
]
[[package]] [[package]]
name = "azalea-brigadier" name = "azalea-brigadier"
@ -200,6 +203,15 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "block-macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "bot" name = "bot"
version = "0.1.0" version = "0.1.0"
@ -971,11 +983,11 @@ checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.36" version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [ dependencies = [
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@ -986,9 +998,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.10" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -1244,13 +1256,13 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.92" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@ -1407,6 +1419,12 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]]
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.19" version = "0.1.19"
@ -1428,12 +1446,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "url" name = "url"
version = "2.2.2" version = "2.2.2"

View file

@ -1,8 +1,11 @@
[package] [package]
edition = "2021"
name = "azalea-block" name = "azalea-block"
version = "0.1.0" version = "0.1.0"
edition = "2021"
[lib]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
block-macros = {path = "./block-macros"}

View file

@ -0,0 +1,14 @@
[package]
edition = "2021"
name = "block-macros"
version = "0.1.0"
[lib]
proc-macro = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
proc-macro2 = "1.0.39"
quote = "1.0.18"
syn = "1.0.95"

View file

@ -0,0 +1,157 @@
use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use std::fmt::Debug;
use syn::{
self, braced,
parse::{Parse, ParseStream, Result},
parse_macro_input,
punctuated::Punctuated,
Data, DeriveInput, Expr, FieldsNamed, Ident, LitInt, Token,
};
struct PropertyDefinition {
name: Ident,
variants: Punctuated<Ident, Token![,]>,
}
struct PropertyDefinitions {
properties: Vec<PropertyDefinition>,
}
struct BlockDefinition {
name: Ident,
behavior: Expr,
properties: Punctuated<Ident, Token![,]>,
}
struct BlockDefinitions {
blocks: Vec<BlockDefinition>,
}
struct MakeBlockStates {
property_definitions: PropertyDefinitions,
block_definitions: BlockDefinitions,
}
impl Parse for PropertyDefinition {
fn parse(input: ParseStream) -> Result<Self> {
// Face {
// Floor,
// Wall,
// Ceiling
// };
let name = input.parse()?;
let variants = input.parse_terminated(Ident::parse)?;
input.parse::<Token![;]>()?;
Ok(PropertyDefinition { name, variants })
}
}
impl Parse for PropertyDefinitions {
fn parse(input: ParseStream) -> Result<Self> {
let mut property_definitions = Vec::new();
while !input.is_empty() {
property_definitions.push(input.parse()?);
}
Ok(PropertyDefinitions {
properties: property_definitions,
})
}
}
impl Parse for BlockDefinition {
fn parse(input: ParseStream) -> Result<Self> {
// acacia_button => BlockBehavior { has_collision: false }, {
// Face,
// Facing,
// Powered
// };
let name = input.parse()?;
input.parse::<Token![=>]>()?;
let behavior = input.parse()?;
input.parse::<Token![,]>()?;
let content;
braced!(content in input);
let properties = content.parse_terminated(Ident::parse)?;
input.parse::<Token![;]>()?;
Ok(BlockDefinition {
name,
behavior,
properties,
})
}
}
impl Parse for BlockDefinitions {
fn parse(input: ParseStream) -> Result<Self> {
let mut blocks = Vec::new();
while !input.is_empty() {
blocks.push(input.parse()?);
}
Ok(BlockDefinitions { blocks })
}
}
impl Parse for MakeBlockStates {
fn parse(input: ParseStream) -> Result<Self> {
// PROPERTIES => { ... } BLOCKS => { ... }
let properties_ident = input.parse::<Ident>()?;
assert_eq!(properties_ident.to_string(), "PROPERTIES");
input.parse::<Token![=>]>()?;
let content;
braced!(content in input);
let properties = content.parse()?;
let blocks_ident = input.parse::<Ident>()?;
assert_eq!(blocks_ident.to_string(), "BLOCKS");
input.parse::<Token![=>]>()?;
let content;
braced!(content in input);
let blocks = content.parse()?;
Ok(MakeBlockStates {
property_definitions: properties,
block_definitions: blocks,
})
}
}
#[proc_macro]
pub fn make_block_states(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as MakeBlockStates);
let mut property_enums = quote! {};
for property in &input.property_definitions.properties {
let mut property_enum_variants = quote! {};
for variant in &property.variants {
property_enum_variants.extend(quote! {
#variant,
});
}
let property_name = property.name;
property_enums.extend(quote! {
#[derive(Debug, Clone, Copy)]
pub enum #property_name {
#property_enum_variants
}
});
}
// let mut block_state_enum_variants = quote! {};
// for block in &input.block_definitions.blocks {
// let block_state_enum_variant = quote! {
// #block.name(#block.behavior, #block.properties)
// };
// block_state_enum_variants.extend(block_state_enum_variant);
// }
quote! {
#property_enums
// #block_state_enum_variants
}
.into()
}

View file

@ -1,88 +1,118 @@
use crate::{behavior::BlockBehavior, properties}; use crate::{behavior::BlockBehavior, properties};
// make_block_states! { make_block_states! {
// acacia_button => BlockBehavior { has_collision: false }, { PROPERTIES => {
// Face, Face {
// Facing, Floor,
// Powered Wall,
// }; Ceiling
// acacia_door => BlockBehavior { has_collision: true }, { };
// Facing, }
// Half, BLOCKS => {
// Hinge, acacia_button => BlockBehavior { has_collision: false }, {
// Open, Face,
// Powered Facing,
// }; Powered
};
acacia_door => BlockBehavior { has_collision: true }, {
Facing,
Half,
Hinge,
Open,
Powered
};
}
}
// #[derive(Debug, Clone, Copy)]
// pub enum Face {
// Floor,
// Wall,
// Ceiling,
// } // }
// the underscore makes it more readable, so i think it's fine to allow it // #[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)] // pub enum Facing {
pub enum BlockState { // North,
AcaciaButton_FloorNorthTrue, // South,
AcaciaButton_WallNorthTrue, // West,
AcaciaButton_CeilingNorthTrue, // East,
} // }
pub trait Block { // #[derive(Debug, Clone, Copy)]
fn behavior(&self) -> BlockBehavior; // pub enum Powered {
} // True,
// False,
// }
#[derive(Debug)] // // the underscore makes it more readable, so i think it's fine to allow it
pub struct AcaciaButtonBlock { // #[allow(non_camel_case_types)]
pub face: properties::Face, // pub enum BlockState {
pub facing: properties::Facing, // AcaciaButton_FloorNorthTrue,
pub powered: properties::Powered, // AcaciaButton_WallNorthTrue,
} // AcaciaButton_CeilingNorthTrue,
// }
impl Block for AcaciaButtonBlock { // pub trait Block {
fn behavior(&self) -> BlockBehavior { // fn behavior(&self) -> BlockBehavior;
BlockBehavior { // }
has_collision: false,
}
}
}
pub struct AcaciaDoorBlock { // #[derive(Debug)]
pub facing: properties::Facing, // pub struct AcaciaButtonBlock {
// pub half: properties::Half, // pub face: properties::Face,
// pub hinge: properties::Hinge, // pub facing: properties::Facing,
// pub open: properties::Open, // pub powered: properties::Powered,
pub powered: properties::Powered, // }
}
impl From<BlockState> for &dyn Block { // impl Block for AcaciaButtonBlock {
fn from(b: BlockState) -> Self { // fn behavior(&self) -> BlockBehavior {
match b { // BlockBehavior {
BlockState::AcaciaButton_FloorNorthTrue => &AcaciaButtonBlock { // has_collision: false,
face: properties::Face::Floor, // }
facing: properties::Facing::North, // }
powered: properties::Powered::True, // }
},
// BlockState::AcaciaButton_WallNorthTrue => todo!(), // pub struct AcaciaDoorBlock {
// BlockState::AcaciaButton_CeilingNorthTrue => todo!(), // pub facing: properties::Facing,
_ => todo!(), // // pub half: properties::Half,
} // // pub hinge: properties::Hinge,
} // // pub open: properties::Open,
} // pub powered: properties::Powered,
impl From<AcaciaButtonBlock> for BlockState { // }
fn from(b: AcaciaButtonBlock) -> Self {
match b { // impl From<BlockState> for &dyn Block {
AcaciaButtonBlock { // fn from(b: BlockState) -> Self {
face: properties::Face::Floor, // match b {
facing: properties::Facing::North, // BlockState::AcaciaButton_FloorNorthTrue => &AcaciaButtonBlock {
powered: properties::Powered::True, // face: properties::Face::Floor,
} => BlockState::AcaciaButton_FloorNorthTrue, // facing: properties::Facing::North,
// AcaciaButtonBlock { // powered: properties::Powered::True,
// face: properties::Face::Wall, // },
// facing: properties::Facing::North, // // BlockState::AcaciaButton_WallNorthTrue => todo!(),
// powered: properties::Powered::True, // // BlockState::AcaciaButton_CeilingNorthTrue => todo!(),
// } => todo!(), // _ => todo!(),
// AcaciaButtonBlock { // }
// face: properties::Face::Ceiling, // }
// facing: properties::Facing::North, // }
// powered: properties::Powered::True, // impl From<AcaciaButtonBlock> for BlockState {
// } => todo!(), // fn from(b: AcaciaButtonBlock) -> Self {
_ => todo!(), // match b {
} // AcaciaButtonBlock {
} // face: properties::Face::Floor,
} // facing: properties::Facing::North,
// powered: properties::Powered::True,
// } => BlockState::AcaciaButton_FloorNorthTrue,
// // AcaciaButtonBlock {
// // face: properties::Face::Wall,
// // facing: properties::Facing::North,
// // powered: properties::Powered::True,
// // } => todo!(),
// // AcaciaButtonBlock {
// // face: properties::Face::Ceiling,
// // facing: properties::Facing::North,
// // powered: properties::Powered::True,
// // } => todo!(),
// _ => todo!(),
// }
// }
// }

View file

@ -1,5 +1,3 @@
pub mod behavior; pub mod behavior;
pub mod blocks; pub mod blocks;
pub mod properties; pub mod properties;
use std::fmt::Debug;

View file

@ -1,20 +0,0 @@
#[derive(Debug, Clone, Copy)]
pub enum Face {
Floor,
Wall,
Ceiling,
}
#[derive(Debug, Clone, Copy)]
pub enum Facing {
North,
South,
West,
East,
}
#[derive(Debug, Clone, Copy)]
pub enum Powered {
True,
False,
}