diff --git a/Macros/lib.rs b/Macros/lib.rs index a4a9090..f0afd71 100644 --- a/Macros/lib.rs +++ b/Macros/lib.rs @@ -10,9 +10,12 @@ use syn::{parse_macro_input, DeriveInput, ItemFn}; pub fn reflect(input: TokenStream) -> TokenStream { let class = parse_macro_input!(input as DeriveInput); let name = &class.ident; + let generics = &class.generics; + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = quote! { - unsafe impl Reflect for #name { + unsafe impl #impl_generics Reflect for #name #ty_generics #where_clause { fn TypeName(&self) -> &'static str { std::any::type_name::() } diff --git a/Source/Class.rs b/Source/Class.rs index 2b51b6f..e2d3213 100644 --- a/Source/Class.rs +++ b/Source/Class.rs @@ -1,8 +1,12 @@ +use crate::Property; use std::any::{type_name, TypeId}; +use std::borrow::Cow; +use std::collections::HashMap; pub struct Class { id: TypeId, - name: &'static str, + name: Cow<'static, str>, + properties: HashMap, Property>, } impl Class { @@ -10,6 +14,7 @@ impl Class { Self { id: TypeId::of::(), name: type_name::().into(), + properties: HashMap::new(), } } @@ -17,7 +22,7 @@ impl Class { self.id } - pub fn GetName(&self) -> &'static str { - self.name + pub fn GetName(&self) -> &str { + &self.name } } diff --git a/Source/Examples/Array.rs b/Source/Examples/Array.rs new file mode 100644 index 0000000..fc0428b --- /dev/null +++ b/Source/Examples/Array.rs @@ -0,0 +1,38 @@ +use crate::*; + +#[derive(Reflect)] +pub struct Array +where + T: Reflect, +{ + inner: Vec, +} + +impl Default for Array +where + T: Reflect, +{ + fn default() -> Self { + Self { inner: Vec::new() } + } +} + +impl Array +where + T: Reflect, +{ + #[function] + pub fn New() -> Self { + Self::default() + } + + #[function] + pub fn Get(&mut self, index: usize) -> Option<&T> { + self.inner.get(index) + } + + #[function] + pub fn GetMut(&mut self, index: usize) -> Option<&mut T> { + self.inner.get_mut(index) + } +} diff --git a/Source/Examples/BinaryHeap.rs b/Source/Examples/BinaryHeap.rs new file mode 100644 index 0000000..7561846 --- /dev/null +++ b/Source/Examples/BinaryHeap.rs @@ -0,0 +1,11 @@ +use crate::*; + +#[derive(Reflect)] +pub struct BinaryHeap +where + T: Reflect, +{ + inner: T, +} + +impl BinaryHeap where T: Reflect {} diff --git a/Source/Examples/BinaryTree.rs b/Source/Examples/BinaryTree.rs new file mode 100644 index 0000000..1373e38 --- /dev/null +++ b/Source/Examples/BinaryTree.rs @@ -0,0 +1,11 @@ +use crate::*; + +#[derive(Reflect)] +pub struct BinaryTree +where + T: Reflect, +{ + inner: T, +} + +impl BinaryTree where T: Reflect {} diff --git a/Source/Examples/HashMap.rs b/Source/Examples/HashMap.rs new file mode 100644 index 0000000..3d6b2e9 --- /dev/null +++ b/Source/Examples/HashMap.rs @@ -0,0 +1,28 @@ +use crate::*; +use std::collections::HashMap as InnerHashMap; +use std::hash::Hash; + +#[derive(Reflect)] +pub struct HashMap +where + K: Reflect + Eq + Hash, + V: Reflect, +{ + inner: InnerHashMap, +} + +impl HashMap +where + K: Reflect + Eq + Hash, + V: Reflect, +{ + #[function] + pub fn Insert(&mut self, key: K, value: V) -> Option { + self.inner.insert(key, value) + } + + #[function] + pub fn Remove(&mut self, key: &K) -> Option { + self.inner.remove(key) + } +} diff --git a/Source/Examples/HashSet.rs b/Source/Examples/HashSet.rs new file mode 100644 index 0000000..1fab967 --- /dev/null +++ b/Source/Examples/HashSet.rs @@ -0,0 +1,12 @@ +use crate::*; +use std::collections::HashSet as InnerHashSet; + +#[derive(Reflect)] +pub struct HashSet +where + T: Reflect, +{ + inner: InnerHashSet, +} + +impl HashSet where T: Reflect {} diff --git a/Source/Examples/LinkedList.rs b/Source/Examples/LinkedList.rs new file mode 100644 index 0000000..05cfac7 --- /dev/null +++ b/Source/Examples/LinkedList.rs @@ -0,0 +1,11 @@ +use crate::*; + +#[derive(Reflect)] +pub struct LinkedList +where + T: Reflect, +{ + inner: T, +} + +impl LinkedList where T: Reflect {} diff --git a/Source/Examples/Queue.rs b/Source/Examples/Queue.rs new file mode 100644 index 0000000..0135ba4 --- /dev/null +++ b/Source/Examples/Queue.rs @@ -0,0 +1,11 @@ +use crate::*; + +#[derive(Reflect)] +pub struct Queue +where + T: Reflect, +{ + inner: T, +} + +impl Queue where T: Reflect {} diff --git a/Source/Examples/Stack.rs b/Source/Examples/Stack.rs new file mode 100644 index 0000000..69ea127 --- /dev/null +++ b/Source/Examples/Stack.rs @@ -0,0 +1,48 @@ +use crate::*; + +#[derive(Reflect)] +pub struct Stack +where + T: Reflect, +{ + inner: Vec, +} + +impl Default for Stack +where + T: Reflect, +{ + fn default() -> Self { + Self { inner: Vec::new() } + } +} + +impl Stack +where + T: Reflect, +{ + #[function] + pub fn New() -> Self { + Self::default() + } + + #[function] + pub fn Push(&mut self, element: T) { + self.inner.push(element); + } + + #[function] + pub fn Peek(&mut self) -> Option<&T> { + self.inner.last() + } + + #[function] + pub fn PeekMut(&mut self) -> Option<&mut T> { + self.inner.last_mut() + } + + #[function] + pub fn Pop(&mut self) -> Option { + self.inner.pop() + } +} diff --git a/Source/Examples/mod.rs b/Source/Examples/mod.rs index b122b1f..d553839 100644 --- a/Source/Examples/mod.rs +++ b/Source/Examples/mod.rs @@ -1,32 +1,31 @@ -use crate::*; +#[path = "Array.rs"] +mod _Array; +pub use self::_Array::Array; -#[derive(Reflect)] -pub struct Foo { - #[property(visible, editable, category = "Default")] - pub a: u32, +#[path = "BinaryTree.rs"] +mod _BinaryTree; +pub use self::_BinaryTree::BinaryTree; - #[property(visible, editable, readwrite, category = "Default")] - pub b: Bar, +#[path = "BinaryHeap.rs"] +mod _BinaryHeap; +pub use self::_BinaryHeap::BinaryHeap; - #[property(visible, readonly, category = "Default")] - pub c: Vec, +#[path = "HashMap.rs"] +mod _HashMap; +pub use self::_HashMap::HashMap; - #[property(hidden)] - pub d: Vec, -} +#[path = "HashSet.rs"] +mod _HashSet; +pub use self::_HashSet::HashSet; -impl Foo { - #[function(callable, multicast, category = "Default")] - pub fn Func(&mut self) {} -} +#[path = "LinkedList.rs"] +mod _LinkedList; +pub use self::_LinkedList::LinkedList; -#[derive(Reflect)] -pub struct Bar { - #[property(visible, editable, category = "Default")] - pub value: f32, -} +#[path = "Queue.rs"] +mod _Queue; +pub use self::_Queue::Queue; -impl Bar { - #[function(event, server, reliable, category = "Default")] - pub fn Func(&mut self) {} -} +#[path = "Stack.rs"] +mod _Stack; +pub use self::_Stack::Stack; diff --git a/Source/Function.rs b/Source/Function.rs new file mode 100644 index 0000000..82ed40e --- /dev/null +++ b/Source/Function.rs @@ -0,0 +1,4 @@ +pub trait Function: Send + Sync + 'static { + type Result; + fn Invoke(&self, args: Args) -> Self::Result; +} diff --git a/Source/Object.rs b/Source/Object.rs index 1190149..51e37de 100644 --- a/Source/Object.rs +++ b/Source/Object.rs @@ -2,22 +2,23 @@ use crate::{Class, Reflect}; use anyhow::Result; use std::sync::Arc; +#[derive(Reflect, Clone)] pub struct Object { inner: Arc, } impl Object { - fn New(obj: impl Reflect) -> Self { + pub fn New(obj: impl Reflect) -> Self { Self { inner: Arc::new(obj), } } - fn InstanceOf(&self, class: &Class) -> bool { + pub fn InstanceOf(&self, class: &Class) -> bool { self.inner.as_ref().type_id() == class.GetId() } - fn GetClass(&self) -> Result<()> { + pub fn GetClass(&self) -> Result<()> { Ok(()) } @@ -25,3 +26,34 @@ impl Object { Ok(()) } } + +#[cfg(test)] +mod Test { + use super::*; + use crate::{Class, Reflect}; + + struct Foo {} + struct Bar {} + + unsafe impl Reflect for Foo { + fn TypeName(&self) -> &'static str { + std::any::type_name::() + } + } + + unsafe impl Reflect for Bar { + fn TypeName(&self) -> &'static str { + std::any::type_name::() + } + } + + #[test] + fn InstanceOf() { + let foo_class: Class = Class::New::(); + let bar_class: Class = Class::New::(); + let foo_instance: Object = Object::New(Foo {}); + + assert!(foo_instance.InstanceOf(&foo_class)); + assert!(!foo_instance.InstanceOf(&bar_class)); + } +} diff --git a/Source/Property.rs b/Source/Property.rs new file mode 100644 index 0000000..ec4932b --- /dev/null +++ b/Source/Property.rs @@ -0,0 +1,5 @@ +use crate::{Object, Value}; +use anyhow::Result; +use std::sync::Arc; + +pub struct Property(Arc Result>); diff --git a/Source/Value.rs b/Source/Value.rs new file mode 100644 index 0000000..7de1fd5 --- /dev/null +++ b/Source/Value.rs @@ -0,0 +1,21 @@ +use crate::Object; + +#[derive(Clone)] +pub enum Value { + Bool(bool), + Char(char), + Int8(i8), + Int16(i16), + Int32(i32), + Int64(i64), + Int128(i128), + UInt8(u8), + UInt16(u16), + UInt32(u32), + UInt64(u64), + UInt128(u128), + Float32(f32), + Float64(f64), + String(String), + Object(Object), +} diff --git a/Source/lib.rs b/Source/lib.rs index cf8f80f..0f80451 100644 --- a/Source/lib.rs +++ b/Source/lib.rs @@ -9,10 +9,22 @@ pub mod Examples; mod _Class; pub use self::_Class::*; +#[path = "Function.rs"] +mod _Function; +pub use self::_Function::*; + #[path = "Object.rs"] mod _Object; pub use self::_Object::*; +#[path = "Property.rs"] +mod _Property; +pub use self::_Property::*; + #[path = "Reflect.rs"] mod _Reflect; pub use self::_Reflect::*; + +#[path = "Value.rs"] +mod _Value; +pub use self::_Value::*;