From 19eebb40852e8de2579a22941ab616df916f0112 Mon Sep 17 00:00:00 2001 From: Werner <26710260+GuilhermeWerner@users.noreply.github.com> Date: Thu, 23 Dec 2021 08:46:30 -0300 Subject: [PATCH] Create initial reflection system --- .cargo/config.toml | 2 ++ Cargo.toml | 20 ++++++++++++++++++++ Macros/Cargo.toml | 18 ++++++++++++++++++ Macros/lib.rs | 24 ++++++++++++++++++++++++ Source/Class.rs | 23 +++++++++++++++++++++++ Source/Examples/mod.rs | 32 ++++++++++++++++++++++++++++++++ Source/Object.rs | 27 +++++++++++++++++++++++++++ Source/Reflect.rs | 3 +++ Source/TypeRegistry.rs | 7 +++++++ Source/lib.rs | 18 ++++++++++++++++++ 10 files changed, 174 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 Cargo.toml create mode 100644 Macros/Cargo.toml create mode 100644 Macros/lib.rs create mode 100644 Source/Class.rs create mode 100644 Source/Examples/mod.rs create mode 100644 Source/Object.rs create mode 100644 Source/Reflect.rs create mode 100644 Source/TypeRegistry.rs create mode 100644 Source/lib.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..0243837 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target-dir = "Binaries" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f6a0c62 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "reflection" +version = "0.0.1" +description = "Reflection" +repository = "https://github.com/GuilhermeWerner/Reflection" +license = "MIT" +edition = "2021" +publish = false + +[lib] +name = "Reflection" +crate-type = ["rlib"] +path = "Source/lib.rs" + +[workspace] +members = ["Macros"] + +[dependencies] +reflection-macros = { path = "Macros" } +anyhow = "1.0" diff --git a/Macros/Cargo.toml b/Macros/Cargo.toml new file mode 100644 index 0000000..f460104 --- /dev/null +++ b/Macros/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "reflection-macros" +version = "0.0.1" +description = "Reflection" +repository = "https://github.com/GuilhermeWerner/Reflection" +license = "MIT" +edition = "2021" +publish = false + +[lib] +name = "Reflection_Macros" +proc-macro = true +path = "lib.rs" + +[dependencies] +proc-macro2 = "1.0.24" +quote = "1.0.7" +syn = { version = "1.0.48", features = ["full"] } diff --git a/Macros/lib.rs b/Macros/lib.rs new file mode 100644 index 0000000..0f9afa4 --- /dev/null +++ b/Macros/lib.rs @@ -0,0 +1,24 @@ +#![allow(non_snake_case)] +#![allow(unused_variables)] +#![recursion_limit = "256"] + +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +#[proc_macro_derive(Reflect, attributes(property))] +pub fn reflect(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + let name = &ast.ident; + + let expanded = quote! { + impl Reflect for #name {} + }; + + expanded.into() +} + +#[proc_macro_attribute] +pub fn function(attr: TokenStream, item: TokenStream) -> TokenStream { + item +} diff --git a/Source/Class.rs b/Source/Class.rs new file mode 100644 index 0000000..2b51b6f --- /dev/null +++ b/Source/Class.rs @@ -0,0 +1,23 @@ +use std::any::{type_name, TypeId}; + +pub struct Class { + id: TypeId, + name: &'static str, +} + +impl Class { + pub fn New() -> Self { + Self { + id: TypeId::of::(), + name: type_name::().into(), + } + } + + pub fn GetId(&self) -> TypeId { + self.id + } + + pub fn GetName(&self) -> &'static str { + self.name + } +} diff --git a/Source/Examples/mod.rs b/Source/Examples/mod.rs new file mode 100644 index 0000000..4c165b5 --- /dev/null +++ b/Source/Examples/mod.rs @@ -0,0 +1,32 @@ +use crate::*; + +#[derive(Reflect)] +pub struct Foo { + #[property(visible, editable, category = "Default")] + pub a: u32, + + #[property(visible, editable, category = "Default")] + pub b: Bar, + + #[property(visible, editable, category = "Default")] + pub c: Vec, + + #[property(visible, editable, category = "Default")] + pub d: Vec, +} + +impl Foo { + #[function(callable, category = "Default")] + pub fn Func(&mut self) {} +} + +#[derive(Reflect)] +pub struct Bar { + #[property(visible, editable, category = "Default")] + pub value: f32, +} + +impl Bar { + #[function(callable, category = "Default")] + pub fn Func(&mut self) {} +} diff --git a/Source/Object.rs b/Source/Object.rs new file mode 100644 index 0000000..1190149 --- /dev/null +++ b/Source/Object.rs @@ -0,0 +1,27 @@ +use crate::{Class, Reflect}; +use anyhow::Result; +use std::sync::Arc; + +pub struct Object { + inner: Arc, +} + +impl Object { + fn New(obj: impl Reflect) -> Self { + Self { + inner: Arc::new(obj), + } + } + + fn InstanceOf(&self, class: &Class) -> bool { + self.inner.as_ref().type_id() == class.GetId() + } + + fn GetClass(&self) -> Result<()> { + Ok(()) + } + + pub fn GetProperty(&self) -> Result<()> { + Ok(()) + } +} diff --git a/Source/Reflect.rs b/Source/Reflect.rs new file mode 100644 index 0000000..51f857e --- /dev/null +++ b/Source/Reflect.rs @@ -0,0 +1,3 @@ +use std::any::Any; + +pub trait Reflect: Any + Send + Sync + 'static {} diff --git a/Source/TypeRegistry.rs b/Source/TypeRegistry.rs new file mode 100644 index 0000000..64c600a --- /dev/null +++ b/Source/TypeRegistry.rs @@ -0,0 +1,7 @@ +use std::any::TypeId; +use std::collections::HashMap; + +#[derive(Default)] +pub struct TypeRegistry { + types: HashMap, +} diff --git a/Source/lib.rs b/Source/lib.rs new file mode 100644 index 0000000..cf8f80f --- /dev/null +++ b/Source/lib.rs @@ -0,0 +1,18 @@ +#![allow(dead_code)] +#![allow(non_snake_case)] + +pub use Reflection_Macros::*; + +pub mod Examples; + +#[path = "Class.rs"] +mod _Class; +pub use self::_Class::*; + +#[path = "Object.rs"] +mod _Object; +pub use self::_Object::*; + +#[path = "Reflect.rs"] +mod _Reflect; +pub use self::_Reflect::*;