reflect: create ReflectedMap
This commit is contained in:
parent
aa3a4a17d7
commit
f345f065c1
|
@ -495,6 +495,10 @@ pub fn derive_reflect_enum(input: &DeriveInput, data_enum: &DataEnum) -> proc_ma
|
|||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn lyra_engine::reflect::Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Ident;
|
||||
use quote::quote;
|
||||
use syn::{Generics, Path, Attribute, GenericParam, parse_macro_input, DeriveInput, TypeParamBound};
|
||||
use syn::{parse_macro_input, Attribute, DeriveInput, GenericParam, Generics, Path, TypeParamBound};
|
||||
|
||||
mod enum_derive;
|
||||
#[allow(unused_imports)]
|
||||
|
@ -71,6 +71,8 @@ impl syn::parse::Parse for ReflectDef {
|
|||
let type_path = Path::parse_mod_style(input)?;
|
||||
//let ident = type_path. //type_path.require_ident()?;
|
||||
let mut generics = input.parse::<Generics>()?;
|
||||
/* let f: Punctuated<GenericParam, Token![,]> = input.parse_terminated(GenericParam::parse, Token![,])?;
|
||||
generics.params = f; */
|
||||
generics.where_clause = input.parse()?;
|
||||
|
||||
Ok(Self {
|
||||
|
@ -134,6 +136,10 @@ pub fn impl_reflect_trait_value(input: TokenStream) -> TokenStream {
|
|||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn lyra_engine::reflect::Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
|
|
|
@ -403,6 +403,10 @@ pub fn derive_reflect_struct(input: &DeriveInput, data_struct: &DataStruct) -> p
|
|||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn lyra_engine::reflect::Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
|
|
|
@ -177,6 +177,10 @@ pub(crate) fn impl_reflect_simple_struct(input: proc_macro::TokenStream) -> proc
|
|||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn lyra_engine::reflect::Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
|
|
|
@ -43,6 +43,10 @@ impl Reflect for DynamicTupleRef {
|
|||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
if let ReflectRef::Tuple(t) = val.reflect_ref() {
|
||||
assert_eq!(t.items_len(), self.items.len(), "The Tuple lengths do not match");
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
use std::any::TypeId;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use lyra_reflect_derive::impl_reflect_trait_value;
|
||||
|
||||
use crate::List;
|
||||
|
||||
use crate::lyra_engine;
|
||||
|
||||
use crate::Struct;
|
||||
use crate::{Reflect, ReflectRef, ReflectMut, util};
|
||||
|
||||
impl_reflect_trait_value!(bool);
|
||||
|
@ -26,11 +31,18 @@ impl_reflect_trait_value!(isize);
|
|||
impl_reflect_trait_value!(f32);
|
||||
impl_reflect_trait_value!(f64);
|
||||
|
||||
impl_reflect_trait_value!(TypeId);
|
||||
impl_reflect_trait_value!(String);
|
||||
|
||||
impl_reflect_trait_value!(::core::option::Option<T: Clone + Reflect>);
|
||||
impl_reflect_trait_value!(::core::result::Result<T: Clone + Reflect, E: Clone + Reflect>);
|
||||
|
||||
impl_reflect_trait_value!(::core::marker::PhantomData<T: 'static>);
|
||||
|
||||
impl_reflect_trait_value!(::std::sync::Arc<T: Reflect>);
|
||||
//impl_reflect_trait_value!(::std::sync::Arc<std::sync::Mutex<T: Reflect>>);
|
||||
//impl_reflect_trait_value!(::std::sync::RwLock<T: Reflect>);
|
||||
|
||||
impl_reflect_trait_value!(::core::ptr::NonNull<T: Reflect>);
|
||||
|
||||
impl<T: Clone + Reflect, const N: usize> Reflect for [T; N] {
|
||||
|
@ -50,6 +62,10 @@ impl<T: Clone + Reflect, const N: usize> Reflect for [T; N] {
|
|||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
if let ReflectRef::Array(arr) = val.reflect_ref() {
|
||||
util::apply_array(self, arr);
|
||||
|
@ -96,6 +112,10 @@ impl<T: Clone + Reflect> Reflect for Vec<T> {
|
|||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
if let ReflectRef::List(list) = val.reflect_ref() {
|
||||
self.apply_list(list);
|
||||
|
@ -127,4 +147,53 @@ impl<T: Clone + Reflect> Reflect for Vec<T> {
|
|||
fn reflect_val_mut(&mut self) -> &mut dyn Reflect {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflect + Struct> Reflect for Arc<RwLock<T>> {
|
||||
fn name(&self) -> String {
|
||||
let t = self.read().unwrap();
|
||||
format!("Arc<RwLock<{}>>", t.name())
|
||||
}
|
||||
|
||||
fn type_id(&self) -> std::any::TypeId {
|
||||
TypeId::of::<Self>()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
.expect(&format!("Cannot reflect assign {} to {}", self.name(), val.name()));
|
||||
*self = val.clone();
|
||||
}
|
||||
|
||||
fn clone_inner(&self) -> Box<dyn Reflect> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reflect_ref(&self) -> ReflectRef {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reflect_mut(&mut self) -> ReflectMut {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reflect_val(&self) -> &dyn Reflect {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn reflect_val_mut(&mut self) -> &mut dyn Reflect {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@ pub use reflected_list::*;
|
|||
pub mod dynamic_tuple;
|
||||
pub use dynamic_tuple::*;
|
||||
|
||||
pub mod reflected_hashmap;
|
||||
pub use reflected_hashmap::*;
|
||||
|
||||
pub mod component;
|
||||
pub use component::*;
|
||||
|
||||
|
@ -55,6 +58,7 @@ pub trait Reflect: Any {
|
|||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
|
||||
|
||||
/// Apply a value to this object.
|
||||
///
|
||||
|
@ -62,6 +66,7 @@ pub trait Reflect: Any {
|
|||
///
|
||||
/// The method panics if
|
||||
/// * the type of `val` is not the same type as `self`
|
||||
// TODO: instead of taking as reference, it would make more sense to take a Box<dyn Reflect>.
|
||||
fn apply(&mut self, val: &dyn Reflect);
|
||||
|
||||
/// Clone self into a [`Box<dyn Reflect>`]
|
||||
|
@ -92,6 +97,7 @@ pub enum ReflectRef<'a> {
|
|||
Array(&'a dyn Array),
|
||||
List(&'a dyn List),
|
||||
Value(&'a dyn Reflect),
|
||||
Map(&'a dyn ReflectedMap),
|
||||
}
|
||||
|
||||
impl<'a> ReflectRef<'a> {
|
||||
|
@ -114,6 +120,7 @@ pub enum ReflectMut<'a> {
|
|||
Array(&'a mut dyn Array),
|
||||
List(&'a mut dyn List),
|
||||
Value(&'a mut dyn Reflect),
|
||||
Map(&'a dyn ReflectedMap),
|
||||
}
|
||||
|
||||
impl<'a> ReflectMut<'a> {
|
||||
|
@ -126,6 +133,7 @@ impl<'a> ReflectMut<'a> {
|
|||
ReflectMut::Array(v) => ReflectRef::Array(*v),
|
||||
ReflectMut::List(v) => ReflectRef::List(*v),
|
||||
ReflectMut::Value(v) => ReflectRef::Value(*v),
|
||||
ReflectMut::Map(v) => ReflectRef::Map(*v),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
use std::{any::TypeId, collections::HashMap, hash::Hash};
|
||||
|
||||
use crate::Reflect;
|
||||
|
||||
pub trait ReflectedMap: Reflect {
|
||||
/// Get the value at the provided `key` in the map.
|
||||
///
|
||||
/// `key` must be the same type as the key in the map.
|
||||
fn reflect_get(&self, key: &dyn Reflect) -> Option<&dyn Reflect>;
|
||||
|
||||
/// Get the nth value in the map.
|
||||
fn reflect_get_nth_value(&self, n: usize) -> Option<&dyn Reflect>;
|
||||
|
||||
/// Get a mutable borrow to the nth value in the map.
|
||||
fn reflect_get_nth_value_mut(&mut self, n: usize) -> Option<&mut dyn Reflect>;
|
||||
|
||||
/// Insert a value at the provided `key` in the map.
|
||||
///
|
||||
/// If there is already a value at `key`, the old value will be returned.
|
||||
fn reflect_insert(&mut self, key: Box<dyn Reflect>, val: Box<dyn Reflect>) -> Option<Box<dyn Reflect>>;
|
||||
|
||||
/// Returns a boolean indicating if the map contains a key as `key`.
|
||||
///
|
||||
/// `key` must be the same type as the key in the map.
|
||||
fn reflect_contains_key(&self, key: &dyn Reflect) -> bool;
|
||||
|
||||
/// Returns the length of the map
|
||||
fn reflect_len(&self) -> usize;
|
||||
|
||||
fn reflect_capacity(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Eq + Hash + Clone + Reflect, V: Clone + Reflect> Reflect for HashMap<K, V> {
|
||||
fn name(&self) -> String {
|
||||
format!("HashMap<?, ?>") // TODO: get types of the generics
|
||||
}
|
||||
|
||||
fn type_id(&self) -> std::any::TypeId {
|
||||
TypeId::of::<Self>()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
.expect("The provided value is not the same type the HashMap");
|
||||
|
||||
for (k, v) in val.iter() {
|
||||
let (k, v) = (k.clone(), v.clone());
|
||||
self.insert(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_inner(&self) -> Box<dyn Reflect> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn reflect_ref(&self) -> crate::ReflectRef {
|
||||
crate::ReflectRef::Map(self)
|
||||
}
|
||||
|
||||
fn reflect_mut(&mut self) -> crate::ReflectMut {
|
||||
crate::ReflectMut::Map(self)
|
||||
}
|
||||
|
||||
fn reflect_val(&self) -> &dyn Reflect {
|
||||
self
|
||||
}
|
||||
|
||||
fn reflect_val_mut(&mut self) -> &mut dyn Reflect {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq + Eq + Hash + Clone + Reflect, V: Clone + Reflect> ReflectedMap for HashMap<K, V> {
|
||||
fn reflect_get(&self, key: &dyn Reflect) -> Option<&dyn Reflect> {
|
||||
let key = key.as_any().downcast_ref::<K>()
|
||||
.expect("The provided key is not the same type as the HashMap's key");
|
||||
|
||||
self.get(key)
|
||||
.map(|v| v.reflect_val())
|
||||
}
|
||||
|
||||
fn reflect_get_nth_value(&self, n: usize) -> Option<&dyn Reflect> {
|
||||
self.values().nth(n)
|
||||
.map(|v| v.reflect_val())
|
||||
}
|
||||
|
||||
fn reflect_get_nth_value_mut(&mut self, n: usize) -> Option<&mut dyn Reflect> {
|
||||
self.values_mut().nth(n)
|
||||
.map(|v| v.reflect_val_mut())
|
||||
}
|
||||
|
||||
fn reflect_insert(&mut self, key: Box<dyn Reflect>, val: Box<dyn Reflect>) -> Option<Box<dyn Reflect>> {
|
||||
let key = key.as_boxed_any();
|
||||
let key = *key.downcast::<K>().expect("The provided key is not the same type as the HashMap's key");
|
||||
|
||||
let val = val.as_boxed_any();
|
||||
let val = *val.downcast::<V>().expect("The provided value is not the same type as the HashMap's value");
|
||||
|
||||
self.insert(key, val)
|
||||
.map(|v| Box::new(v) as Box<dyn Reflect>)
|
||||
}
|
||||
|
||||
fn reflect_contains_key(&self, key: &dyn Reflect) -> bool {
|
||||
let key = key.as_any().downcast_ref::<K>()
|
||||
.expect("The provided key is not the same type as the HashMap's key");
|
||||
|
||||
self.contains_key(key)
|
||||
}
|
||||
|
||||
fn reflect_len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
fn reflect_capacity(&self) -> usize {
|
||||
self.capacity()
|
||||
}
|
||||
}
|
|
@ -24,6 +24,10 @@ macro_rules! impl_reflect_tuple {
|
|||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_boxed_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, val: &dyn Reflect) {
|
||||
let val = val.as_any().downcast_ref::<Self>()
|
||||
|
|
Loading…
Reference in New Issue