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 lyra_ecs::World;
use lyra_ecs::{AtomicRef, AtomicRefMut, World};
extern crate self as lyra_reflect;
@ -250,46 +250,46 @@ pub trait FromType<T> {
pub trait ReflectWorldExt {
/// 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.
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
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.
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.
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 {
fn get_type_registry(&self) -> Ref<TypeRegistry> {
fn get_type_registry(&self) -> AtomicRef<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>()
}
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>();
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 {
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>();
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 {
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>();
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
#[derive(Default, Clone)]
@ -44,19 +44,19 @@ impl TypeRegistry {
}
}
pub trait TypeData: std::any::Any {
fn as_any(&self) -> &dyn std::any::Any;
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
pub trait TypeData: Send + Sync + Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn boxed_clone(&self) -> Box<dyn TypeData>;
}
impl<T: Clone + 'static> TypeData for T {
fn as_any(&self) -> &dyn std::any::Any {
impl<T: Clone + Send + Sync + Any> TypeData for T {
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
fn as_any_mut(&mut self) -> &mut dyn Any {
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};
@ -8,20 +8,20 @@ use crate::{Reflect, FromType};
pub struct ReflectedResource {
pub type_id: TypeId,
fn_reflect: for<'a> fn (world: &'a World) -> Option<Ref<'a, dyn Reflect>>,
fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<RefMut<'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<AtomicRefMut<'a, dyn Reflect>>,
fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>,
fn_refl_insert: fn (world: &mut World, this: Box<dyn Reflect>),
}
impl ReflectedResource {
/// 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)
}
/// 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)
}
@ -41,11 +41,15 @@ impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
type_id: TypeId::of::<T>(),
fn_reflect: |world: &World| {
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| {
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 {
world.try_get_resource_ptr::<T>()