108 lines
3.4 KiB
Rust
108 lines
3.4 KiB
Rust
|
use std::{any::{TypeId, type_name, Any}, collections::HashMap, marker::PhantomData, sync::Arc};
|
||
|
|
||
|
use super::{field::Field, method::Method, Reflect, Value};
|
||
|
|
||
|
/// A trait that a struct would implement
|
||
|
pub trait Struct: Reflect {
|
||
|
/// Attempt to get a borrow of a field.
|
||
|
fn field(&self, name: &str) -> Option<&dyn Reflect>;
|
||
|
|
||
|
/// Attempt to get a mutable borrow of a field.
|
||
|
fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
|
||
|
|
||
|
/// Returns the number of fields in the struct.
|
||
|
fn fields_len(&self) -> usize;
|
||
|
|
||
|
/// Returns a borrow of a field at `idx`. Returns None if the index is out of range.
|
||
|
fn field_at(&self, idx: usize) -> Option<&dyn Reflect>;
|
||
|
|
||
|
/// Returns a mutable borrow of a field at `idx`. Returns None if the index is out of range.
|
||
|
fn field_at_mut(&mut self, idx: usize) -> Option<&mut dyn Reflect>;
|
||
|
|
||
|
/// Returns the name of the field at the index.
|
||
|
fn field_name_at(&self, idx: usize) -> Option<&str>;
|
||
|
|
||
|
/// Sets the field named `name`. Returns a boolean indicating if it was successful.
|
||
|
fn set_field(&mut self, name: &str, val: &dyn Reflect) -> bool;
|
||
|
|
||
|
/// Sets the field at `idx`. Returns a boolean indicating if it was successful.
|
||
|
fn set_field_at(&mut self, idx: usize, val: &dyn Reflect) -> bool;
|
||
|
|
||
|
/// Returns the type of the field named `name`.
|
||
|
fn field_type(&self, name: &str) -> Option<&'static str>;
|
||
|
|
||
|
/// Returns the type of the field at `idx`.
|
||
|
fn field_type_at(&self, idx: usize) -> Option<&'static str>;
|
||
|
|
||
|
// not really sure if any of these can actually be used with the new reflection system
|
||
|
|
||
|
fn method(&self, name: &str) -> Option<&Method>;
|
||
|
fn method_at(&self, idx: usize) -> Option<&Method>;
|
||
|
fn methods_len(&self) -> usize;
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use std::any::TypeId;
|
||
|
|
||
|
use lyra_reflect_derive::Reflect;
|
||
|
|
||
|
use crate::{Reflect, ReflectRef, ReflectMut};
|
||
|
|
||
|
use super::Struct;
|
||
|
use crate::lyra_engine;
|
||
|
|
||
|
#[derive(Clone, Copy, Reflect)]
|
||
|
struct Vec2 {
|
||
|
x: f32,
|
||
|
y: f32,
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn struct_ref() {
|
||
|
let v = Vec2 {
|
||
|
x: 5.0,
|
||
|
y: 10.0
|
||
|
};
|
||
|
let v = Box::new(v) as Box<dyn Reflect>;
|
||
|
|
||
|
if let ReflectRef::Struct(s) = v.reflect_ref() {
|
||
|
let x = s.field("x").unwrap();
|
||
|
let x = x.as_any().downcast_ref::<f32>().unwrap();
|
||
|
assert_eq!(*x, 5.0);
|
||
|
|
||
|
let y = s.field("y").unwrap();
|
||
|
let y = y.as_any().downcast_ref::<f32>().unwrap();
|
||
|
assert_eq!(*y, 10.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn struct_mut() {
|
||
|
let v = Vec2 {
|
||
|
x: 5.0,
|
||
|
y: 10.0
|
||
|
};
|
||
|
let mut v = Box::new(v) as Box<dyn Reflect>;
|
||
|
|
||
|
if let ReflectMut::Struct(s) = v.reflect_mut() {
|
||
|
let x = s.field_mut("x").unwrap();
|
||
|
let x = x.as_any_mut().downcast_mut::<f32>().unwrap();
|
||
|
*x = *x * 2.0;
|
||
|
|
||
|
let y = s.field_mut("y").unwrap();
|
||
|
let y = y.as_any_mut().downcast_mut::<f32>().unwrap();
|
||
|
*y = *y * 2.0;
|
||
|
}
|
||
|
|
||
|
if let ReflectRef::Struct(s) = v.reflect_ref() {
|
||
|
let x = s.field("x").unwrap();
|
||
|
let x = x.as_any().downcast_ref::<f32>().unwrap();
|
||
|
assert_eq!(*x, 10.0);
|
||
|
|
||
|
let y = s.field("y").unwrap();
|
||
|
let y = y.as_any().downcast_ref::<f32>().unwrap();
|
||
|
assert_eq!(*y, 20.0);
|
||
|
}
|
||
|
}
|
||
|
}
|