use core::{
any::TypeId,
ops::{Deref, DerefMut},
};
use crate::{resource::Resource, world::World};
use bevy_reflect::{
std_traits::ReflectDefault, PartialReflect, Reflect, ReflectFromReflect, TypePath,
TypeRegistry, TypeRegistryArc,
};
mod bundle;
mod component;
mod entity_commands;
mod from_world;
mod map_entities;
mod resource;
use bevy_utils::prelude::DebugName;
pub use bundle::{ReflectBundle, ReflectBundleFns};
pub use component::{ReflectComponent, ReflectComponentFns};
pub use entity_commands::ReflectCommandExt;
pub use from_world::{ReflectFromWorld, ReflectFromWorldFns};
pub use map_entities::ReflectMapEntities;
pub use resource::{ReflectResource, ReflectResourceFns};
#[derive(Resource, Clone, Default)]
pub struct AppTypeRegistry(pub TypeRegistryArc);
impl Deref for AppTypeRegistry {
type Target = TypeRegistryArc;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for AppTypeRegistry {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AppTypeRegistry {
#[cfg(feature = "reflect_auto_register")]
pub fn new_with_derived_types() -> Self {
let app_registry = AppTypeRegistry::default();
app_registry.write().register_derived_types();
app_registry
}
}
#[cfg(feature = "reflect_functions")]
#[derive(Resource, Clone, Default)]
pub struct AppFunctionRegistry(pub bevy_reflect::func::FunctionRegistryArc);
#[cfg(feature = "reflect_functions")]
impl Deref for AppFunctionRegistry {
type Target = bevy_reflect::func::FunctionRegistryArc;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg(feature = "reflect_functions")]
impl DerefMut for AppFunctionRegistry {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub fn from_reflect_with_fallback<T: Reflect + TypePath>(
reflected: &dyn PartialReflect,
world: &mut World,
registry: &TypeRegistry,
) -> T {
#[inline(never)]
fn type_erased(
reflected: &dyn PartialReflect,
world: &mut World,
registry: &TypeRegistry,
id: TypeId,
name: DebugName,
) -> alloc::boxed::Box<dyn core::any::Any> {
let (value, source) = if let Some(value) = registry
.get_type_data::<ReflectFromReflect>(id)
.and_then(|reflect_from_reflect| reflect_from_reflect.from_reflect(reflected))
{
(value, "FromReflect")
}
else if let Some(reflect_default) = registry.get_type_data::<ReflectDefault>(id) {
let mut value = reflect_default.default();
value.apply(reflected);
(value, "Default")
} else if let Some(reflect_from_world) = registry.get_type_data::<ReflectFromWorld>(id) {
let mut value = reflect_from_world.from_world(world);
value.apply(reflected);
(value, "FromWorld")
} else {
panic!(
"Couldn't create an instance of `{name}` using the reflected `FromReflect`, \
`Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \
or `#[reflect(FromWorld)]`?",
);
};
assert_eq!(
value.as_any().type_id(),
id,
"The registration for the reflected `{source}` trait for the type `{name}` produced \
a value of a different type",
);
value
}
*type_erased(
reflected,
world,
registry,
TypeId::of::<T>(),
DebugName::type_name::<T>(),
)
.downcast::<T>()
.unwrap()
}