diff options
author | HampusM <hampus@hampusmat.com> | 2024-02-26 20:05:27 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-02-26 20:16:27 +0100 |
commit | 815d04da602c58ed8b13eeb612fe73180204039d (patch) | |
tree | c3703e598656c070edbc271ccaa9117e071d6d4f /ecs-macros | |
parent | 1019924a29527eba2c8ec8bd976ece6ed76075b0 (diff) |
fix(ecs): make Component trait not automatic & add derive macro
Diffstat (limited to 'ecs-macros')
-rw-r--r-- | ecs-macros/Cargo.toml | 13 | ||||
-rw-r--r-- | ecs-macros/src/lib.rs | 79 |
2 files changed, 92 insertions, 0 deletions
diff --git a/ecs-macros/Cargo.toml b/ecs-macros/Cargo.toml new file mode 100644 index 0000000..792ca34 --- /dev/null +++ b/ecs-macros/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "ecs-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.35" +syn = { version = "2.0.51", features = ["full"] } +proc-macro2 = "1.0.78" + diff --git a/ecs-macros/src/lib.rs b/ecs-macros/src/lib.rs new file mode 100644 index 0000000..e37d6a4 --- /dev/null +++ b/ecs-macros/src/lib.rs @@ -0,0 +1,79 @@ +use proc_macro::TokenStream; +use quote::{quote, ToTokens}; +use syn::spanned::Spanned; +use syn::{parse, Ident, Item, ItemEnum, ItemStruct, ItemUnion}; + +#[proc_macro_derive(Component)] +pub fn component_derive(input: TokenStream) -> TokenStream +{ + let item: TypeItem = parse::<Item>(input).unwrap().try_into().unwrap(); + + let item_ident = item.ident(); + + quote! { + impl ecs::component::Component for #item_ident + { + fn as_any_mut(&mut self) -> &mut dyn std::any::Any + { + self + } + + fn as_any(&self) -> &dyn std::any::Any + { + self + } + } + + impl ecs::system::Input for #item_ident {} + } + .into() +} + +enum TypeItem +{ + Struct(ItemStruct), + Enum(ItemEnum), + Union(ItemUnion), +} + +impl TypeItem +{ + fn ident(&self) -> &Ident + { + match self { + Self::Struct(struct_item) => &struct_item.ident, + Self::Enum(enum_item) => &enum_item.ident, + Self::Union(union_item) => &union_item.ident, + } + } +} + +impl TryFrom<Item> for TypeItem +{ + type Error = syn::Error; + + fn try_from(item: Item) -> Result<Self, Self::Error> + { + match item { + Item::Struct(struct_item) => Ok(Self::Struct(struct_item)), + Item::Enum(enum_item) => Ok(Self::Enum(enum_item)), + Item::Union(union_item) => Ok(Self::Union(union_item)), + _ => Err(syn::Error::new( + item.span(), + "Expected a struct, a enum or a union", + )), + } + } +} + +impl ToTokens for TypeItem +{ + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) + { + match self { + Self::Struct(struct_item) => struct_item.to_tokens(tokens), + Self::Enum(enum_item) => enum_item.to_tokens(tokens), + Self::Union(union_item) => union_item.to_tokens(tokens), + } + } +} |