lyra-engine/lyra-reflect/src/reflected_struct.rs

100 lines
3.2 KiB
Rust

use super::{method::Method, Reflect};
/// 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 crate::{Reflect, ReflectRef, ReflectMut};
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);
}
}
}