aboutsummaryrefslogtreecommitdiff
path: root/azalea-block
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-27 19:34:09 -0500
committermat <github@matdoes.dev>2022-05-27 19:34:09 -0500
commit88bc6d16602c163d122685997dc269d5d97a93a2 (patch)
tree959c68a4d21d7b832aaa04aebbf6e7412f620367 /azalea-block
parentaac64d013546c8be3b992af63d70150155386c11 (diff)
downloadazalea-drasl-88bc6d16602c163d122685997dc269d5d97a93a2.tar.xz
Start making block macro
Diffstat (limited to 'azalea-block')
-rw-r--r--azalea-block/Cargo.toml5
-rw-r--r--azalea-block/block-macros/Cargo.toml14
-rw-r--r--azalea-block/block-macros/src/lib.rs157
-rw-r--r--azalea-block/src/blocks.rs188
-rw-r--r--azalea-block/src/lib.rs2
-rw-r--r--azalea-block/src/properties.rs20
6 files changed, 284 insertions, 102 deletions
diff --git a/azalea-block/Cargo.toml b/azalea-block/Cargo.toml
index ea43e8ae..edeba385 100644
--- a/azalea-block/Cargo.toml
+++ b/azalea-block/Cargo.toml
@@ -1,8 +1,11 @@
[package]
+edition = "2021"
name = "azalea-block"
version = "0.1.0"
-edition = "2021"
+
+[lib]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+block-macros = {path = "./block-macros"}
diff --git a/azalea-block/block-macros/Cargo.toml b/azalea-block/block-macros/Cargo.toml
new file mode 100644
index 00000000..03b19e1d
--- /dev/null
+++ b/azalea-block/block-macros/Cargo.toml
@@ -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"
diff --git a/azalea-block/block-macros/src/lib.rs b/azalea-block/block-macros/src/lib.rs
new file mode 100644
index 00000000..20ec5f3e
--- /dev/null
+++ b/azalea-block/block-macros/src/lib.rs
@@ -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()
+}
diff --git a/azalea-block/src/blocks.rs b/azalea-block/src/blocks.rs
index f6f33a89..6bc82a20 100644
--- a/azalea-block/src/blocks.rs
+++ b/azalea-block/src/blocks.rs
@@ -1,88 +1,118 @@
use crate::{behavior::BlockBehavior, properties};
-// make_block_states! {
-// acacia_button => BlockBehavior { has_collision: false }, {
-// Face,
-// Facing,
-// Powered
-// };
-// acacia_door => BlockBehavior { has_collision: true }, {
-// Facing,
-// Half,
-// Hinge,
-// Open,
-// Powered
-// };
+make_block_states! {
+ PROPERTIES => {
+ Face {
+ Floor,
+ Wall,
+ Ceiling
+ };
+ }
+ BLOCKS => {
+ acacia_button => BlockBehavior { has_collision: false }, {
+ Face,
+ 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
-#[allow(non_camel_case_types)]
-pub enum BlockState {
- AcaciaButton_FloorNorthTrue,
- AcaciaButton_WallNorthTrue,
- AcaciaButton_CeilingNorthTrue,
-}
+// #[derive(Debug, Clone, Copy)]
+// pub enum Facing {
+// North,
+// South,
+// West,
+// East,
+// }
-pub trait Block {
- fn behavior(&self) -> BlockBehavior;
-}
+// #[derive(Debug, Clone, Copy)]
+// pub enum Powered {
+// True,
+// False,
+// }
-#[derive(Debug)]
-pub struct AcaciaButtonBlock {
- pub face: properties::Face,
- pub facing: properties::Facing,
- pub powered: properties::Powered,
-}
+// // the underscore makes it more readable, so i think it's fine to allow it
+// #[allow(non_camel_case_types)]
+// pub enum BlockState {
+// AcaciaButton_FloorNorthTrue,
+// AcaciaButton_WallNorthTrue,
+// AcaciaButton_CeilingNorthTrue,
+// }
-impl Block for AcaciaButtonBlock {
- fn behavior(&self) -> BlockBehavior {
- BlockBehavior {
- has_collision: false,
- }
- }
-}
+// pub trait Block {
+// fn behavior(&self) -> BlockBehavior;
+// }
-pub struct AcaciaDoorBlock {
- pub facing: properties::Facing,
- // pub half: properties::Half,
- // pub hinge: properties::Hinge,
- // pub open: properties::Open,
- pub powered: properties::Powered,
-}
+// #[derive(Debug)]
+// pub struct AcaciaButtonBlock {
+// pub face: properties::Face,
+// pub facing: properties::Facing,
+// pub powered: properties::Powered,
+// }
-impl From<BlockState> for &dyn Block {
- fn from(b: BlockState) -> Self {
- match b {
- BlockState::AcaciaButton_FloorNorthTrue => &AcaciaButtonBlock {
- face: properties::Face::Floor,
- facing: properties::Facing::North,
- powered: properties::Powered::True,
- },
- // BlockState::AcaciaButton_WallNorthTrue => todo!(),
- // BlockState::AcaciaButton_CeilingNorthTrue => todo!(),
- _ => todo!(),
- }
- }
-}
-impl From<AcaciaButtonBlock> for BlockState {
- fn from(b: AcaciaButtonBlock) -> Self {
- 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!(),
- }
- }
-}
+// impl Block for AcaciaButtonBlock {
+// fn behavior(&self) -> BlockBehavior {
+// BlockBehavior {
+// has_collision: false,
+// }
+// }
+// }
+
+// pub struct AcaciaDoorBlock {
+// pub facing: properties::Facing,
+// // pub half: properties::Half,
+// // pub hinge: properties::Hinge,
+// // pub open: properties::Open,
+// pub powered: properties::Powered,
+// }
+
+// impl From<BlockState> for &dyn Block {
+// fn from(b: BlockState) -> Self {
+// match b {
+// BlockState::AcaciaButton_FloorNorthTrue => &AcaciaButtonBlock {
+// face: properties::Face::Floor,
+// facing: properties::Facing::North,
+// powered: properties::Powered::True,
+// },
+// // BlockState::AcaciaButton_WallNorthTrue => todo!(),
+// // BlockState::AcaciaButton_CeilingNorthTrue => todo!(),
+// _ => todo!(),
+// }
+// }
+// }
+// impl From<AcaciaButtonBlock> for BlockState {
+// fn from(b: AcaciaButtonBlock) -> Self {
+// 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!(),
+// }
+// }
+// }
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs
index db94d081..30f2aadc 100644
--- a/azalea-block/src/lib.rs
+++ b/azalea-block/src/lib.rs
@@ -1,5 +1,3 @@
pub mod behavior;
pub mod blocks;
pub mod properties;
-
-use std::fmt::Debug;
diff --git a/azalea-block/src/properties.rs b/azalea-block/src/properties.rs
deleted file mode 100644
index ac81fcb3..00000000
--- a/azalea-block/src/properties.rs
+++ /dev/null
@@ -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,
-}