reflect: fix type registry from changes with ecs resources

This commit is contained in:
SeanOMik 2024-03-30 22:42:41 -04:00
parent e00d0d71d1
commit e5018c8258
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
4 changed files with 34 additions and 29 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use_nix

View File

@ -2,7 +2,7 @@
use std::{any::TypeId, any::Any, cell::{Ref, RefMut}}; use std::{any::TypeId, any::Any, cell::{Ref, RefMut}};
use lyra_ecs::World; use lyra_ecs::{AtomicRef, AtomicRefMut, World};
extern crate self as lyra_reflect; extern crate self as lyra_reflect;
@ -250,46 +250,46 @@ pub trait FromType<T> {
pub trait ReflectWorldExt { pub trait ReflectWorldExt {
/// Retrieves the type registry from the world. /// Retrieves the type registry from the world.
fn get_type_registry(&self) -> Ref<TypeRegistry>; fn get_type_registry(&self) -> AtomicRef<TypeRegistry>;
/// Retrieves the type registry mutably from the world. /// Retrieves the type registry mutably from the world.
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry>; fn get_type_registry_mut(&self) -> AtomicRefMut<TypeRegistry>;
/// Get a registered type from the type registry. Returns `None` if the type is not registered /// Get a registered type from the type registry. Returns `None` if the type is not registered
fn get_type<T>(&self, type_id: TypeId) -> Option<Ref<RegisteredType>>; fn get_type<T>(&self, type_id: TypeId) -> Option<AtomicRef<RegisteredType>>;
/// Get a mutable registered type from the type registry in the world. returns `None` if the type is not registered. /// Get a mutable registered type from the type registry in the world. returns `None` if the type is not registered.
fn get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>>; fn get_type_mut<T>(&self, type_id: TypeId) -> Option<AtomicRefMut<RegisteredType>>;
/// Get a registered type, or register a new type and return it. /// Get a registered type, or register a new type and return it.
fn get_type_or_default<T>(&self, type_id: TypeId) -> RefMut<RegisteredType>; fn get_type_or_default<T>(&self, type_id: TypeId) -> AtomicRefMut<RegisteredType>;
} }
impl ReflectWorldExt for World { impl ReflectWorldExt for World {
fn get_type_registry(&self) -> Ref<TypeRegistry> { fn get_type_registry(&self) -> AtomicRef<TypeRegistry> {
self.get_resource::<TypeRegistry>() self.get_resource::<TypeRegistry>()
} }
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry> { fn get_type_registry_mut(&self) -> AtomicRefMut<TypeRegistry> {
self.get_resource_mut::<TypeRegistry>() self.get_resource_mut::<TypeRegistry>()
} }
fn get_type<T>(&self, type_id: TypeId) -> Option<Ref<RegisteredType>> { fn get_type<T>(&self, type_id: TypeId) -> Option<AtomicRef<RegisteredType>> {
let r = self.get_resource::<TypeRegistry>(); let r = self.get_resource::<TypeRegistry>();
if r.has_type(type_id) { if r.has_type(type_id) {
Some(Ref::map(r, |tr| tr.get_type(type_id).unwrap())) Some(AtomicRef::map(r, |tr| tr.get_type(type_id).unwrap()))
} else { } else {
None None
} }
} }
fn get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>> { fn get_type_mut<T>(&self, type_id: TypeId) -> Option<AtomicRefMut<RegisteredType>> {
let r = self.get_resource_mut::<TypeRegistry>(); let r = self.get_resource_mut::<TypeRegistry>();
if r.has_type(type_id) { if r.has_type(type_id) {
Some(RefMut::map(r, |tr| tr.get_type_mut(type_id).unwrap())) Some(AtomicRefMut::map(r, |tr| tr.get_type_mut(type_id).unwrap()))
} else { } else {
None None
} }
} }
fn get_type_or_default<T>(&self, type_id: TypeId) -> RefMut<RegisteredType> { fn get_type_or_default<T>(&self, type_id: TypeId) -> AtomicRefMut<RegisteredType> {
let r = self.get_resource_mut::<TypeRegistry>(); let r = self.get_resource_mut::<TypeRegistry>();
RefMut::map(r, |tr| tr.get_type_or_default(type_id)) AtomicRefMut::map(r, |tr| tr.get_type_or_default(type_id))
} }
} }

View File

@ -1,4 +1,4 @@
use std::{any::{TypeId, type_name}, collections::HashMap, ops::Deref}; use std::{any::{type_name, Any, TypeId}, collections::HashMap, ops::Deref};
/// Storage for /// Storage for
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -44,19 +44,19 @@ impl TypeRegistry {
} }
} }
pub trait TypeData: std::any::Any { pub trait TypeData: Send + Sync + Any {
fn as_any(&self) -> &dyn std::any::Any; fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn std::any::Any; fn as_any_mut(&mut self) -> &mut dyn Any;
fn boxed_clone(&self) -> Box<dyn TypeData>; fn boxed_clone(&self) -> Box<dyn TypeData>;
} }
impl<T: Clone + 'static> TypeData for T { impl<T: Clone + Send + Sync + Any> TypeData for T {
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { fn as_any_mut(&mut self) -> &mut dyn Any {
self self
} }

View File

@ -1,6 +1,6 @@
use std::{any::{Any, TypeId}, cell::{Ref, RefMut}, ptr::NonNull}; use std::{any::{Any, TypeId}, mem, ptr::NonNull};
use lyra_ecs::{World, ResourceObject}; use lyra_ecs::{AtomicRef, AtomicRefMut, ResourceObject, World};
use crate::{Reflect, FromType}; use crate::{Reflect, FromType};
@ -8,20 +8,20 @@ use crate::{Reflect, FromType};
pub struct ReflectedResource { pub struct ReflectedResource {
pub type_id: TypeId, pub type_id: TypeId,
fn_reflect: for<'a> fn (world: &'a World) -> Option<Ref<'a, dyn Reflect>>, fn_reflect: for<'a> fn (world: &'a World) -> Option<AtomicRef<'a, dyn Reflect>>,
fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>>, fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<AtomicRefMut<'a, dyn Reflect>>,
fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>, fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>,
fn_refl_insert: fn (world: &mut World, this: Box<dyn Reflect>), fn_refl_insert: fn (world: &mut World, this: Box<dyn Reflect>),
} }
impl ReflectedResource { impl ReflectedResource {
/// Retrieves the reflected resource from the world. /// Retrieves the reflected resource from the world.
pub fn reflect<'a>(&self, world: &'a World) -> Option<Ref<'a, dyn Reflect>> { pub fn reflect<'a>(&self, world: &'a World) -> Option<AtomicRef<'a, dyn Reflect>> {
(self.fn_reflect)(world) (self.fn_reflect)(world)
} }
/// Retrieves a mutable reflected resource from the world. /// Retrieves a mutable reflected resource from the world.
pub fn reflect_mut<'a>(&self, world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>> { pub fn reflect_mut<'a>(&self, world: &'a mut World) -> Option<AtomicRefMut<'a, dyn Reflect>> {
(self.fn_reflect_mut)(world) (self.fn_reflect_mut)(world)
} }
@ -41,11 +41,15 @@ impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
type_id: TypeId::of::<T>(), type_id: TypeId::of::<T>(),
fn_reflect: |world: &World| { fn_reflect: |world: &World| {
world.try_get_resource::<T>() world.try_get_resource::<T>()
.map(|r| r as Ref<dyn Reflect>) .map(|r| {
AtomicRef::map(r, |r| r as &dyn Reflect)
})
}, },
fn_reflect_mut: |world: &mut World| { fn_reflect_mut: |world: &mut World| {
world.try_get_resource_mut::<T>() world.try_get_resource_mut::<T>()
.map(|r| r as RefMut<dyn Reflect>) .map(|r| {
AtomicRefMut::map(r, |r| r as &mut dyn Reflect)
})
}, },
fn_reflect_ptr: |world: &mut World| unsafe { fn_reflect_ptr: |world: &mut World| unsafe {
world.try_get_resource_ptr::<T>() world.try_get_resource_ptr::<T>()