use std::{any::TypeId, cell::{Ref, RefMut}}; 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, /// Inserts component into entity in the world fn_insert: for<'a> fn (world: &'a mut World, entity: Entity, component: &dyn Reflect), /// Inserts component into a bundle fn_bundle_insert: for<'a> fn (dynamic_bundle: &'a mut DynamicBundle, component: &dyn Reflect), fn_reflect: for<'a> fn (world: &'a World, entity: Entity) -> Option>, fn_reflect_mut: for<'a> fn (world: &'a mut World, entity: Entity) -> Option>, } impl ReflectedComponent { /// Insert the reflected component into an entity. pub fn insert(&self, world: &mut World, entity: Entity, component: &dyn Reflect) { (self.fn_insert)(world, entity, component); } /// Insert this component into a DynamicBundle pub fn bundle_insert(&self, dynamic_bundle: &mut DynamicBundle, component: &dyn Reflect) { (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> { (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> { (self.fn_reflect_mut)(world, entity) } } impl FromType for ReflectedComponent { fn from_type() -> Self { ReflectedComponent { type_id: TypeId::of::(), info: ComponentInfo::new::(), fn_insert: |world: &mut World, entity: Entity, component: &dyn Reflect| { let mut c = C::default(); c.apply(component); world.insert(entity, (c,)); }, fn_bundle_insert: |bundle: &mut DynamicBundle, component: &dyn Reflect| { let mut c = C::default(); c.apply(component); bundle.push(c); }, fn_reflect: |world: &World, entity: Entity| { world.view_one::<&C>(entity) .get().map(|c| c as Ref) }, fn_reflect_mut: |world: &mut World, entity: Entity| { world.view_one::<&mut C>(entity) .get().map(|c| c as RefMut) }, } } }