2024-02-23 21:39:51 +00:00
|
|
|
use std::{any::{Any, TypeId}, cell::{Ref, RefMut}};
|
2024-01-20 05:54:36 +00:00
|
|
|
|
|
|
|
use lyra_ecs::{Component, ComponentInfo, World, Entity, DynamicBundle};
|
|
|
|
|
|
|
|
use crate::{Reflect, FromType};
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct ReflectedComponent {
|
|
|
|
pub type_id: TypeId,
|
|
|
|
pub info: ComponentInfo,
|
|
|
|
//value: Value,
|
|
|
|
//from_world:
|
|
|
|
|
|
|
|
//from_world: for<'a> fn (world: &'a mut World) -> Box<dyn Reflect>,
|
|
|
|
/// Inserts component into entity in the world
|
2024-02-23 21:39:51 +00:00
|
|
|
fn_insert: for<'a> fn (world: &'a mut World, entity: Entity, component: Box<dyn Reflect>),
|
2024-01-20 05:54:36 +00:00
|
|
|
/// Inserts component into a bundle
|
2024-02-23 21:39:51 +00:00
|
|
|
fn_bundle_insert: for<'a> fn (dynamic_bundle: &'a mut DynamicBundle, component: Box<dyn Reflect>),
|
2024-01-20 05:54:36 +00:00
|
|
|
fn_reflect: for<'a> fn (world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>>,
|
|
|
|
fn_reflect_mut: for<'a> fn (world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ReflectedComponent {
|
|
|
|
/// Insert the reflected component into an entity.
|
2024-02-23 21:39:51 +00:00
|
|
|
pub fn insert(&self, world: &mut World, entity: Entity, component: Box<dyn Reflect>) {
|
2024-01-20 05:54:36 +00:00
|
|
|
(self.fn_insert)(world, entity, component);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Insert this component into a DynamicBundle
|
2024-02-23 21:39:51 +00:00
|
|
|
pub fn bundle_insert(&self, dynamic_bundle: &mut DynamicBundle, component: Box<dyn Reflect>) {
|
2024-01-20 05:54:36 +00:00
|
|
|
(self.fn_bundle_insert)(dynamic_bundle, component)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieves a reflected component from an entity.
|
|
|
|
pub fn reflect<'a>(&'a self, world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>> {
|
|
|
|
(self.fn_reflect)(world, entity)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieves a reflected component from an entity.
|
|
|
|
pub fn reflect_mut<'a>(&'a mut self, world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>> {
|
|
|
|
(self.fn_reflect_mut)(world, entity)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-23 21:39:51 +00:00
|
|
|
impl<C: Component + Reflect> FromType<C> for ReflectedComponent {
|
2024-01-20 05:54:36 +00:00
|
|
|
fn from_type() -> Self {
|
|
|
|
ReflectedComponent {
|
|
|
|
type_id: TypeId::of::<C>(),
|
|
|
|
info: ComponentInfo::new::<C>(),
|
2024-02-23 21:39:51 +00:00
|
|
|
fn_insert: |world: &mut World, entity: Entity, component: Box<dyn Reflect>| {
|
|
|
|
let c = component as Box<dyn Any>;
|
|
|
|
let c = c.downcast::<C>()
|
|
|
|
.expect("Provided a non-matching type to ReflectedComponent insert method!");
|
|
|
|
let c = *c;
|
2024-01-20 05:54:36 +00:00
|
|
|
world.insert(entity, (c,));
|
|
|
|
},
|
2024-02-23 21:39:51 +00:00
|
|
|
fn_bundle_insert: |bundle: &mut DynamicBundle, component: Box<dyn Reflect>| {
|
|
|
|
let c = component as Box<dyn Any>;
|
|
|
|
let c = c.downcast::<C>()
|
|
|
|
.expect("Provided a non-matching type to ReflectedComponent insert method!");
|
|
|
|
let c = *c;
|
2024-01-20 05:54:36 +00:00
|
|
|
bundle.push(c);
|
|
|
|
},
|
|
|
|
fn_reflect: |world: &World, entity: Entity| {
|
|
|
|
world.view_one::<&C>(entity)
|
|
|
|
.get().map(|c| c as Ref<dyn Reflect>)
|
|
|
|
},
|
|
|
|
fn_reflect_mut: |world: &mut World, entity: Entity| {
|
|
|
|
world.view_one::<&mut C>(entity)
|
|
|
|
.get().map(|c| c as RefMut<dyn Reflect>)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|