cleaned up type info fetching from Reflect + put type info in a struct

This commit is contained in:
Dmitry Stepanov
2026-05-15 11:32:33 +03:00
parent 0a6b7a9bf1
commit e7f1b1d4d8
37 changed files with 325 additions and 466 deletions
+1 -1
View File
@@ -175,7 +175,7 @@ impl SelectionContainer for AudioBusSelection {
.bus_graph_ref()
.try_get_bus_ref(*h)
.ok()
.map(|bus| bus.doc().to_string())
.map(|bus| bus.type_info_ref().doc_comment.to_string())
})
}
}
+6 -6
View File
@@ -428,8 +428,8 @@ impl<F: EntityGetter> SetPropertyCommand<F> {
"Failed to set property {}! Incompatible types. \
Target property: {}. Value: {}!",
self.path,
property.type_name(),
current_value.type_name()
property.type_info_ref().type_name,
current_value.type_info_ref().type_name
);
self.value = Some(current_value);
}
@@ -462,7 +462,7 @@ impl<F: EntityGetter> SetPropertyCommand<F> {
Target property: {}. Value: {}!",
self.path,
field_type_name,
value.type_name()
value.type_info_ref().type_name
);
value
@@ -485,7 +485,7 @@ impl<F: EntityGetter> SetPropertyCommand<F> {
Target property: {}. Value: {}!",
self.path,
field_type_name,
value.type_name()
value.type_info_ref().type_name
);
value
@@ -550,8 +550,8 @@ impl<F: EntityGetter> CommandTrait for AddCollectionItemCommand<F> {
err!(
"Failed to push item to {} collection. Type mismatch {} and {}!",
self.path,
item.type_name(),
list.type_name()
item.type_info_ref().type_name,
list.type_info_ref().type_name
);
self.item = Some(item);
}
+6 -1
View File
@@ -115,7 +115,12 @@ impl SelectionContainer for NavmeshSelection {
fn provide_docs(&self, controller: &dyn SceneController, engine: &Engine) -> Option<String> {
let game_scene = controller.downcast_ref::<GameScene>()?;
let scene = &engine.scenes[game_scene.scene];
Some(scene.graph[self.navmesh_node()].doc().to_string())
Some(
scene.graph[self.navmesh_node()]
.type_info_ref()
.doc_comment
.to_string(),
)
}
}
+1 -1
View File
@@ -216,7 +216,7 @@ impl Toolbar {
inner_type_name: std::any::type_name::<N>().to_string(),
handle: Default::default(),
inner_type_id: TypeId::of::<N>(),
derived_type_ids: N::derived_types().to_vec(),
derived_type_ids: N::type_info().derived_types.to_vec(),
children: vec![],
};
+4 -2
View File
@@ -208,14 +208,16 @@ where
engine.scenes[game_scene.scene]
.graph
.node(ErasedHandle::from(self.animation_player).into())
.doc()
.type_info_ref()
.doc_comment
.to_string(),
)
} else {
controller.downcast_ref::<UiScene>().map(|ui| {
ui.ui
.node(ErasedHandle::from(self.animation_player).into())
.doc()
.type_info_ref()
.doc_comment
.to_string()
})
}
@@ -220,7 +220,7 @@ impl<T: Reflect> Control for HandlePropertyEditor<T> {
NodeSelectorMessage::Selection(vec![SelectedHandle {
handle: self.value.into(),
inner_type_id: TypeId::of::<T>(),
derived_type_ids: T::derived_types().to_vec(),
derived_type_ids: T::type_info().derived_types.to_vec(),
}]),
);
}
+1 -1
View File
@@ -349,7 +349,7 @@ impl InspectorPlugin {
ui.send(self.inspector, InspectorMessage::Context(context));
ui.send_sync(
self.type_name_text,
TextMessage::Text(format!("Type Name: {}", obj.type_name())),
TextMessage::Text(format!("Type Name: {}", obj.type_info_ref().type_name)),
);
}
+2 -2
View File
@@ -203,7 +203,7 @@ where
descriptor.children_properties.push(PropertyDescriptor {
path: item_path.clone(),
display_name: format!("[{i}]"),
type_name: item.type_name().to_owned(),
type_name: item.type_info_ref().type_name.to_owned(),
type_id: item.type_id(),
read_only: field_info.read_only,
children_properties: object_to_property_tree(
@@ -260,7 +260,7 @@ where
descriptor.children_properties.push(PropertyDescriptor {
path: item_path.clone(),
display_name: format!("[{key_str}]"),
type_name: value.type_name().to_owned(),
type_name: value.type_info_ref().type_name.to_owned(),
type_id: value.type_id(),
read_only: field_info.read_only,
children_properties: object_to_property_tree(
+1 -1
View File
@@ -173,7 +173,7 @@ impl<T: Reflect> From<Handle<T>> for SelectedHandle {
fn from(value: Handle<T>) -> Self {
Self {
inner_type_id: TypeId::of::<T>(),
derived_type_ids: T::derived_types().to_vec(),
derived_type_ids: T::type_info().derived_types.to_vec(),
handle: value.into(),
}
}
+1 -1
View File
@@ -136,7 +136,7 @@ impl SelectionContainer for UiSelection {
.ui
.try_get_node(*h)
.ok()
.map(|n| n.doc().to_string())
.map(|n| n.type_info_ref().doc_comment.to_string())
})
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ impl WorldViewerDataProvider for UiSceneWorldViewerDataProvider<'_> {
Cow::Owned(format!(
"{} [{}]",
n.name(),
make_pretty_type_name(Reflect::type_name(n))
make_pretty_type_name(n.type_info_ref().type_name)
))
})
}
+1 -1
View File
@@ -125,7 +125,7 @@ impl SelectionContainer for GraphSelection {
let scene = &engine.scenes[game_scene.scene];
self.nodes
.first()
.map(|h| scene.graph[*h].doc().to_string())
.map(|h| scene.graph[*h].type_info_ref().doc_comment.to_string())
}
}
+14 -28
View File
@@ -245,7 +245,7 @@ fn struct_set_field_body(ty_args: &args::TypeArgs) -> Option<TokenStream2> {
}
Err(current) => {
let mut field_type_name = "(none)";
self.find_field_mut(name, &mut |field| { field_type_name = field.unwrap().type_name() });
self.find_field_mut(name, &mut |field| { field_type_name = field.unwrap().type_info_ref().type_name });
Err(SetFieldError::InvalidValue{field_type_name, value: current})
}
})
@@ -263,7 +263,7 @@ fn struct_set_field_body(ty_args: &args::TypeArgs) -> Option<TokenStream2> {
let value = opt_value.take().unwrap();
match field {
Some(f) => func(f.set(value).map_err(|value| SetFieldError::InvalidValue {
field_type_name: f.type_name(),
field_type_name: f.type_info_ref().type_name,
value,
})),
None => func(Err(SetFieldError::NoSuchField {
@@ -449,39 +449,25 @@ fn gen_impl(
quote! {
#[allow(warnings)]
impl #impl_generics Reflect for #ty_ident #ty_generics #where_clause {
fn source_path() -> &'static str {
file!()
}
#try_clone_box
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
fn derived_types() -> &'static [std::any::TypeId] {
static ARRAY: std::sync::LazyLock<Vec<std::any::TypeId>> = std::sync::LazyLock::new(|| vec![
fn type_info() -> TypeInfo where Self: Sized {
static DERIVED_TYPES: std::sync::LazyLock<Vec<std::any::TypeId>> = std::sync::LazyLock::new(|| vec![
#types
]);
&ARRAY
TypeInfo {
source_path: file!(),
type_name: std::any::type_name::<Self>(),
assembly_name: #assembly_name,
doc_comment: #doc,
derived_types: &DERIVED_TYPES,
}
}
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
Self::derived_types()
fn type_info_ref(&self) -> TypeInfo {
Self::type_info()
}
fn doc(&self) -> &'static str {
#doc
}
fn assembly_name(&self) -> &'static str {
#assembly_name
}
fn type_assembly_name() -> &'static str {
#assembly_name
}
#try_clone_box
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
#metadata_ref
+1 -1
View File
@@ -77,7 +77,7 @@ fn doc_comments() {
multiline doc comment."
);
});
assert_eq!(s.doc(), " Struct doc comment.");
assert_eq!(s.type_info_ref().doc_comment, " Struct doc comment.");
}
#[test]
+15 -28
View File
@@ -23,6 +23,7 @@
#![warn(missing_docs)]
use crate::reflect::TypeInfo;
use crate::{reflect::prelude::*, type_traits::prelude::*, visitor::prelude::*, SafeLock};
use fxhash::FxHashMap;
use parking_lot::{Mutex, MutexGuard};
@@ -168,32 +169,18 @@ static CONTENT_METADATA: FieldMetadata = FieldMetadata {
};
impl Reflect for DynTypeWrapper {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId] {
&[]
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
type_name::<Self>()
}
fn doc(&self) -> &'static str {
""
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
fn type_info_ref(&self) -> TypeInfo {
Self::type_info()
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
@@ -280,7 +267,7 @@ impl DynTypeContainer {
Some(wrapper) => match wrapper.0.take::<T>() {
Ok(casted) => Ok(casted),
Err(value) => {
let actual_type_name = Reflect::type_name(&*value);
let actual_type_name = (*value).type_info_ref().type_name;
self.0.replace(DynTypeWrapper(value));
Err(DynTypeError::TypeCast {
actual_type_name,
@@ -308,7 +295,7 @@ impl DynTypeContainer {
(value as &dyn Any)
.downcast_ref()
.ok_or_else(|| DynTypeError::TypeCast {
actual_type_name: Reflect::type_name(value),
actual_type_name: value.type_info_ref().type_name,
requested_type_name: type_name::<T>(),
})
}
@@ -317,7 +304,7 @@ impl DynTypeContainer {
/// to the caller.
pub fn data_mut<T: DynType>(&mut self) -> Result<&mut T, DynTypeError> {
let value = self.value_mut().ok_or(DynTypeError::Empty)?;
let actual_type_name = Reflect::type_name(value);
let actual_type_name = value.type_info_ref().type_name;
(value as &mut dyn Any)
.downcast_mut()
.ok_or_else(|| DynTypeError::TypeCast {
@@ -413,7 +400,7 @@ impl DynTypeConstructorContainer {
DynTypeConstructorDefinition {
name: name.to_string(),
constructor: Box::new(|| Box::new(T::default())),
assembly_name: A::type_assembly_name(),
assembly_name: A::type_info().assembly_name,
},
);
+11 -28
View File
@@ -19,7 +19,7 @@
// SOFTWARE.
use crate::pool::ObjectOrVariant;
use crate::reflect::ReflectHandle;
use crate::reflect::{ReflectHandle, TypeInfo};
use crate::{
combine_uuids, pool::INVALID_GENERATION, reflect::prelude::*, uuid_provider,
visitor::prelude::*, TypeUuidProvider,
@@ -111,41 +111,24 @@ static GENERATION_METADATA: FieldMetadata = FieldMetadata {
};
impl<T: Reflect> Reflect for Handle<T> {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: T::type_info().derived_types,
}
}
fn derived_types() -> &'static [TypeId]
where
Self: Sized,
{
T::derived_types()
fn type_info_ref(&self) -> TypeInfo {
Self::type_info()
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(*self))
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
type_name::<Self>()
}
fn doc(&self) -> &'static str {
""
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
func(&[
{
+12 -31
View File
@@ -41,10 +41,10 @@
//! friendliness.
use crate::{reflect::prelude::*, visitor::prelude::*};
use std::any::type_name;
use std::cell::UnsafeCell;
use std::fmt::{Display, Formatter};
use std::{
any::TypeId,
fmt::Debug,
future::Future,
marker::PhantomData,
@@ -55,6 +55,7 @@ pub mod handle;
pub mod multiborrow;
pub mod payload;
use crate::reflect::TypeInfo;
pub use handle::*;
pub use multiborrow::*;
pub use payload::*;
@@ -147,36 +148,24 @@ where
P: PayloadContainer<Element = T> + Reflect,
Pool<T, P>: Clone,
{
#[inline]
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId]
where
Self: Sized,
{
&[]
fn type_info_ref(&self) -> TypeInfo {
Self::type_info()
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(self.clone()))
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
#[inline]
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
#[inline]
fn doc(&self) -> &'static str {
""
}
#[inline]
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
func(&[])
@@ -216,14 +205,6 @@ where
Ok(Box::new(this))
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn field_direct_ref(&self, _index: usize) -> Option<FieldRef> {
None
}
+10 -26
View File
@@ -134,14 +134,18 @@ impl<T: Reflect + Clone> Reflect for Box<T> {
macro_rules! impl_reflect_inner_mutability {
($self:ident, $acquire_lock_guard:block, $into_inner:block) => {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: std::any::type_name::<T>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: T::type_info().derived_types,
}
}
fn derived_types() -> &'static [std::any::TypeId] {
// TODO: This seems to be impossible to implement because of `?Sized` trait bound
// up above.
&[]
fn type_info_ref(&self) -> TypeInfo {
Self::type_info()
}
fn try_clone_box(&$self) -> Option<Box<dyn Reflect>> {
@@ -149,26 +153,6 @@ macro_rules! impl_reflect_inner_mutability {
Some(Box::new(guard.clone()))
}
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
T::derived_types()
}
fn type_name(&$self) -> &'static str {
std::any::type_name::<T>()
}
fn doc(&$self) -> &'static str {
""
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn fields_ref(&$self, func: &mut dyn FnMut(&[FieldRef])) {
let guard = $acquire_lock_guard;
guard.fields_ref(func)
+38 -79
View File
@@ -139,39 +139,32 @@ macro_rules! newtype_reflect {
#[macro_export]
macro_rules! delegate_reflect {
() => {
fn source_path() -> &'static str {
file!()
fn type_info() -> $crate::reflect::TypeInfo {
$crate::reflect::TypeInfo {
source_path: file!(),
type_name: std::any::type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [std::any::TypeId] {
// TODO
&[]
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.deref().type_info_ref();
$crate::reflect::TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(self.clone()))
}
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
self.deref().type_name()
}
fn doc(&self) -> &'static str {
self.deref().doc()
}
fn assembly_name(&self) -> &'static str {
self.deref().assembly_name()
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn fields_ref(&self, func: &mut dyn FnMut(&[$crate::reflect::FieldRef])) {
self.deref().fields_ref(func)
}
@@ -298,41 +291,24 @@ macro_rules! delegate_reflect {
#[macro_export]
macro_rules! blank_reflect {
() => {
fn source_path() -> &'static str {
file!()
fn type_info() -> $crate::reflect::TypeInfo {
$crate::reflect::TypeInfo {
source_path: file!(),
type_name: std::any::type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [std::any::TypeId]
where
Self: Sized,
{
&[]
fn type_info_ref(&self) -> $crate::reflect::TypeInfo {
Self::type_info()
}
fn try_clone_box(&self) -> Option<Box<dyn $crate::reflect::Reflect>> {
Some(Box::new(self.clone()))
}
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
fn doc(&self) -> &'static str {
""
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn fields_ref(&self, func: &mut dyn FnMut(&[$crate::reflect::FieldRef])) {
func(&[])
}
@@ -399,41 +375,24 @@ macro_rules! blank_reflect {
#[macro_export]
macro_rules! blank_reflect_ref {
() => {
fn source_path() -> &'static str {
file!()
fn type_info() -> $crate::reflect::TypeInfo {
$crate::reflect::TypeInfo {
source_path: file!(),
type_name: std::any::type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [std::any::TypeId]
where
Self: Sized,
{
&[]
fn type_info_ref(&self) -> $crate::reflect::TypeInfo {
Self::type_info()
}
fn try_clone_box(&self) -> Option<Box<dyn $crate::reflect::Reflect>> {
None
}
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
fn doc(&self) -> &'static str {
""
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn fields_ref(&self, func: &mut dyn FnMut(&[$crate::reflect::FieldRef])) {
func(&[])
}
+40 -28
View File
@@ -50,9 +50,38 @@ pub mod prelude {
pub use super::{
FieldMetadata, FieldMut, FieldRef, FieldValue, Reflect, ReflectArray, ReflectHashMap,
ReflectInheritableVariable, ReflectList, ResolvePath, SetFieldByPathError, SetFieldError,
TypeInfo,
};
}
/// A set of useful information about a type that can be queried at runtime.
pub struct TypeInfo {
/// Name of the file where the type is located. Usually, it is just `file!()` macro call result.
pub source_path: &'static str,
/// The actual name of the type in human-readable form. Typically, it just contains the result
/// of calling `std::any::type_name::<T>()`.
pub type_name: &'static str,
/// A parent assembly name of the type that implements this trait.
///
/// ## Important notes for implementors
///
/// Use proc-macro (`#[derive(Reflect)]`) to ensure that this field contains the correct assembly
/// name. In other words - there's no guarantee, that any implementation other than proc-macro
/// will return a correct name of the assembly. Alternatively, you can use `env!("CARGO_PKG_NAME")`
/// as an implementation.
pub assembly_name: &'static str,
/// A documentation of the type.
pub doc_comment: &'static str,
/// A set of types that are derived from this type. Derived here does not mean classic OOPs
/// derived class, it is just a "link" between this type an others. It is widely used to link
/// an actual type with its wrapper type (which typically contains `Box<dyn SomeTrait>`).
pub derived_types: &'static [TypeId],
}
/// A trait for runtime reflection.
///
/// ## Code Generation
@@ -119,22 +148,18 @@ pub mod prelude {
/// for every type that should support `Reflect` trait. It is a good compromise between development speed
/// and the quality of the string output.
pub trait Reflect: Any + Debug {
fn source_path() -> &'static str
/// Returns the info about the type that implements this trait. The result of the call of this
/// method can be different from the call of [`Self::type_info_ref`] on an instance of the type.
fn type_info() -> TypeInfo
where
Self: Sized;
fn derived_types() -> &'static [TypeId]
where
Self: Sized;
/// Returns the info about the type that implements this trait. The result of the call of this
/// method can be different from the call of [`Self::type_info`].
fn type_info_ref(&self) -> TypeInfo;
fn try_clone_box(&self) -> Option<Box<dyn Reflect>>;
fn query_derived_types(&self) -> &'static [TypeId];
fn type_name(&self) -> &'static str;
fn doc(&self) -> &'static str;
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef]));
fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut]));
@@ -154,22 +179,6 @@ pub trait Reflect: Any + Debug {
fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>>;
/// Returns a parent assembly name of the type that implements this trait. **WARNING:** You should use
/// proc-macro (`#[derive(Reflect)]`) to ensure that this method will return correct assembly
/// name. In other words - there's no guarantee, that any implementation other than proc-macro
/// will return a correct name of the assembly. Alternatively, you can use `env!("CARGO_PKG_NAME")`
/// as an implementation.
fn assembly_name(&self) -> &'static str;
/// Returns a parent assembly name of the type that implements this trait. **WARNING:** You should use
/// proc-macro (`#[derive(Reflect)]`) to ensure that this method will return correct assembly
/// name. In other words - there's no guarantee, that any implementation other than proc-macro
/// will return a correct name of the assembly. Alternatively, you can use `env!("CARGO_PKG_NAME")`
/// as an implementation.
fn type_assembly_name() -> &'static str
where
Self: Sized;
/// Tries to get a shared reference to a field at the specified index. Returns [`None`] in two cases:
/// 1) The type does not have such field
/// 2) The type uses interior mutability. This case is special - pretty much every type with
@@ -211,7 +220,7 @@ pub trait Reflect: Any + Debug {
let value = opt_value.take().unwrap();
match field {
Some(f) => func(f.set(value).map_err(|value| SetFieldError::InvalidValue {
field_type_name: f.type_name(),
field_type_name: f.type_info_ref().type_name,
value,
})),
None => func(Err(SetFieldError::NoSuchField {
@@ -1120,6 +1129,9 @@ mod test {
#[test]
fn test_derived() {
let base = Base;
assert_eq!(base.query_derived_types(), &[TypeId::of::<Derived>()])
assert_eq!(
base.type_info_ref().derived_types,
&[TypeId::of::<Derived>()]
)
}
}
+27 -38
View File
@@ -27,6 +27,7 @@ use crate::{
visitor::{prelude::*, VisitorFlags},
};
use bitflags::bitflags;
use std::any::type_name;
use std::{
any::{Any, TypeId},
cell::Cell,
@@ -401,44 +402,32 @@ impl<T> Reflect for InheritableVariable<T>
where
T: Reflect + Clone + PartialEq + Debug,
{
#[inline]
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: T::type_info().derived_types,
}
}
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.value.type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(self.value.clone()))
}
fn derived_types() -> &'static [TypeId]
where
Self: Sized,
{
T::derived_types()
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
#[inline]
fn type_name(&self) -> &'static str {
self.value.type_name()
}
#[inline]
fn doc(&self) -> &'static str {
self.value.doc()
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
#[inline]
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
self.value.fields_ref(func)
@@ -579,8 +568,8 @@ where
}
None => {
result = Err(InheritError::TypesMismatch {
left_type: self.inner_value_ref().type_name(),
right_type: parent.inner_value_ref().type_name(),
left_type: self.inner_value_ref().type_info_ref().type_name,
right_type: parent.inner_value_ref().type_info_ref().type_name,
});
}
}
@@ -690,8 +679,8 @@ pub fn try_inherit_properties(
if child_type_id != parent_type_id {
return Err(InheritError::TypesMismatch {
left_type: (*child).type_name(),
right_type: (*parent).type_name(),
left_type: (*child).type_info_ref().type_name,
right_type: (*parent).type_info_ref().type_name,
});
}
@@ -1193,14 +1182,14 @@ mod test {
fn inheritable_variable_type_name() {
let v = InheritableVariable::from(42);
assert_eq!(Reflect::type_name(&v), "i32");
assert_eq!(v.type_info_ref().type_name, "i32");
}
#[test]
fn inheritable_variable_doc() {
let v = InheritableVariable::from(42);
assert_eq!(v.doc(), "");
assert_eq!(v.type_info_ref().doc_comment, "");
}
#[test]
+1 -1
View File
@@ -93,7 +93,7 @@ impl<Node, Ctx> GraphNodeConstructor<Node, Ctx> {
default: Arc::new(|| Node::from(Inner::default())),
variants: vec![],
group: "",
assembly_name: Inner::type_assembly_name(),
assembly_name: Inner::type_info().assembly_name,
}
}
+27 -27
View File
@@ -236,7 +236,10 @@ where
// Handle derived entities handles.
entity.as_handle_mut(&mut |handle| {
if let Some(handle) = handle {
if handle.query_derived_types().contains(&TypeId::of::<N>())
if handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
@@ -375,7 +378,10 @@ where
entity.as_handle_mut(&mut |handle| {
if let Some(handle) = handle {
if do_map
&& handle.query_derived_types().contains(&TypeId::of::<N>())
&& handle
.type_info_ref()
.derived_types
.contains(&TypeId::of::<N>())
&& handle.reflect_is_some()
&& !self.try_map_reflect(handle)
{
@@ -1628,6 +1634,7 @@ mod test {
NameProvider,
};
use fyrox_resource::{untyped::UntypedResource, Resource, ResourceData};
use std::any::type_name;
use std::marker::PhantomData;
use std::{
any::{Any, TypeId},
@@ -1718,24 +1725,25 @@ mod test {
}
impl Reflect for Node {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn type_name(&self) -> &'static str {
self.0.deref().type_name()
}
fn doc(&self) -> &'static str {
self.0.deref().doc()
}
fn assembly_name(&self) -> &'static str {
self.0.deref().assembly_name()
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.0.deref().type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
@@ -1779,14 +1787,6 @@ mod test {
self.0.deref_mut().find_field_mut(name, func)
}
fn derived_types() -> &'static [TypeId] {
&[]
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(self.clone()))
}
@@ -2089,7 +2089,7 @@ mod test {
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
self.nodes
.try_borrow(handle)
.map(|n| n.0.deref().query_derived_types().to_vec())
.map(|n| n.0.deref().type_info_ref().derived_types.to_vec())
}
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Result<&'static str, PoolError> {
+2 -2
View File
@@ -344,7 +344,7 @@ fn is_script_belongs_to_plugin(
.map()
.get(&script_id)
{
if constructor.assembly_name == plugin.assembly_name() {
if constructor.assembly_name == plugin.type_info_ref().assembly_name {
return true;
}
}
@@ -359,7 +359,7 @@ fn is_node_belongs_to_plugin(
let node_id = (*node).id();
if let Some(constructor) = serialization_context.node_constructors.map().get(&node_id) {
if constructor.assembly_name == plugin.assembly_name() {
if constructor.assembly_name == plugin.type_info_ref().assembly_name {
return true;
}
}
+2 -2
View File
@@ -2550,7 +2550,7 @@ impl Engine {
plugin.prepare_to_reload();
let plugin_type_id = plugin.as_loaded_ref().type_id();
let plugin_assembly_name = plugin.as_loaded_ref().assembly_name();
let plugin_assembly_name = plugin.as_loaded_ref().type_info_ref().assembly_name;
// Collect all the data that belongs to the plugin
let mut scenes_state = Vec::new();
@@ -2642,7 +2642,7 @@ impl Engine {
let data = resource.lock();
if let ResourceState::Ok { ref data, .. } = data.state {
data.as_reflect(&mut |reflect| {
if reflect.assembly_name() == plugin_assembly_name {
if reflect.type_info_ref().assembly_name == plugin_assembly_name {
resources_to_reload.insert(resource.clone());
}
})
+8 -8
View File
@@ -101,14 +101,14 @@ mod test {
let widget = WidgetBuilder::new().build(&ui.build_ctx());
let status = Status::Stopped;
assert_eq!(var.assembly_name(), "fyrox-core");
assert_eq!(base.assembly_name(), "fyrox-impl");
assert_eq!(widget.assembly_name(), "fyrox-ui");
assert_eq!(status.assembly_name(), "fyrox-sound");
assert_eq!(var.type_info_ref().assembly_name, "fyrox-core");
assert_eq!(base.type_info_ref().assembly_name, "fyrox-impl");
assert_eq!(widget.type_info_ref().assembly_name, "fyrox-ui");
assert_eq!(status.type_info_ref().assembly_name, "fyrox-sound");
assert_eq!(ImmutableString::type_assembly_name(), "fyrox-core");
assert_eq!(Base::type_assembly_name(), "fyrox-impl");
assert_eq!(Widget::type_assembly_name(), "fyrox-ui");
assert_eq!(Status::type_assembly_name(), "fyrox-sound");
assert_eq!(ImmutableString::type_info().assembly_name, "fyrox-core");
assert_eq!(Base::type_info().assembly_name, "fyrox-impl");
assert_eq!(Widget::type_info().assembly_name, "fyrox-ui");
assert_eq!(Status::type_info().assembly_name, "fyrox-sound");
}
}
+1 -1
View File
@@ -2173,7 +2173,7 @@ impl SceneGraph for Graph {
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
self.pool
.try_borrow(handle)
.map(|n| Box::deref(&n.0).query_derived_types().to_vec())
.map(|n| Box::deref(&n.0).type_info_ref().derived_types.to_vec())
}
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Result<&'static str, PoolError> {
+18 -24
View File
@@ -63,6 +63,7 @@ use crate::{
},
};
use fyrox_core::{define_as_any_trait, pool::ObjectOrVariantHelper};
use std::any::type_name;
use std::{
any::TypeId,
fmt::Debug,
@@ -571,32 +572,25 @@ impl Visit for Node {
}
impl Reflect for Node {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId] {
&[]
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
self.0.deref().type_name()
}
fn doc(&self) -> &'static str {
self.0.deref().doc()
}
fn assembly_name(&self) -> &'static str {
self.0.deref().assembly_name()
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.0.deref().type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
+4 -2
View File
@@ -68,13 +68,15 @@ impl ScriptConstructorContainer {
where
T: TypeUuidProvider + ScriptTrait + Default,
{
let type_info = T::type_info();
let old = self.map.safe_lock().insert(
T::type_uuid(),
ScriptConstructor {
constructor: Box::new(|| Script::new(T::default())),
name: name.to_owned(),
source_path: T::source_path(),
assembly_name: T::type_assembly_name(),
source_path: type_info.source_path,
assembly_name: type_info.assembly_name,
},
);
+20 -25
View File
@@ -40,10 +40,12 @@ use crate::{
scene::{base::NodeScriptMessage, node::Node, Scene},
};
use fyrox_core::pool::ObjectOrVariant;
use fyrox_core::reflect::TypeInfo;
pub use fyrox_core_derive::ScriptMessagePayload;
use fyrox_graph::SceneGraph;
use std::any::type_name;
use std::{
any::{Any, TypeId},
any::Any,
fmt::{Debug, Formatter},
ops::{Deref, DerefMut},
str::FromStr,
@@ -723,32 +725,25 @@ impl TypeUuidProvider for Script {
}
impl Reflect for Script {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId] {
&[]
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
self.instance.type_name()
}
fn doc(&self) -> &'static str {
self.instance.doc()
}
fn assembly_name(&self) -> &'static str {
self.instance.assembly_name()
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.instance.type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
+18 -34
View File
@@ -22,7 +22,7 @@
use crate::{core::reflect::prelude::*, ResourceData, ResourceLoadError, TypedResourceData};
use fyrox_core::reflect::ReflectHandle;
use std::any::{Any, TypeId};
use std::any::{type_name, Any};
use std::fmt::{Debug, Display};
use std::path::PathBuf;
use std::{
@@ -88,36 +88,31 @@ impl Display for LoadError {
pub struct ResourceDataWrapper(pub Box<dyn ResourceData>);
impl Reflect for ResourceDataWrapper {
fn source_path() -> &'static str
where
Self: Sized,
{
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId]
where
Self: Sized,
{
&[]
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.deref().type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Reflect::try_clone_box(&*self.0)
}
fn query_derived_types(&self) -> &'static [TypeId] {
self.deref().query_derived_types()
}
fn type_name(&self) -> &'static str {
self.deref().type_name()
}
fn doc(&self) -> &'static str {
self.deref().doc()
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
self.deref().fields_ref(func)
}
@@ -150,17 +145,6 @@ impl Reflect for ResourceDataWrapper {
self.deref_mut().set(value)
}
fn assembly_name(&self) -> &'static str {
env!("CARGO_PKG_NAME")
}
fn type_assembly_name() -> &'static str
where
Self: Sized,
{
env!("CARGO_PKG_NAME")
}
fn field_direct_ref(&self, index: usize) -> Option<FieldRef<'_, '_>> {
self.deref().field_direct_ref(index)
}
+3 -1
View File
@@ -502,7 +502,9 @@ impl UntypedResource {
/// loaded resources (in [`ResourceState::Ok`] state).
pub fn data_type_name(&self) -> Option<String> {
match self.lock().state {
ResourceState::Ok { ref data, .. } => Some(Reflect::type_name(&**data).to_string()),
ResourceState::Ok { ref data, .. } => {
Some((**data).type_info_ref().type_name.to_string())
}
_ => None,
}
}
+2 -2
View File
@@ -457,7 +457,7 @@ impl Grid {
let Some(row) = rows.get_mut(node.row()) else {
Log::err(format!(
"Node row out of bounds: {} row:{}, column:{}",
Reflect::type_name(node),
node.type_info_ref().type_name,
node.row(),
node.column()
));
@@ -466,7 +466,7 @@ impl Grid {
let Some(col) = cols.get_mut(node.column()) else {
Log::err(format!(
"Node column out of bounds: {} row:{}, column:{}",
Reflect::type_name(node),
node.type_info_ref().type_name,
node.row(),
node.column()
));
+3 -3
View File
@@ -575,7 +575,7 @@ impl Inspector {
object: &mut dyn Reflect,
clipboard_value: &mut Option<Box<dyn Reflect>>,
) {
let object_type_name = object.type_name();
let object_type_name = object.type_info_ref().type_name;
match msg {
InspectorMessage::PropertyContextMenuOpened { path } => {
@@ -614,7 +614,7 @@ impl Inspector {
"Unable to clone the field {}, because it is non-cloneable! \
Field type is: {}",
path,
field.type_name()
field.type_info_ref().type_name
);
}
} else {
@@ -656,7 +656,7 @@ impl Inspector {
"Unable to clone the field {}, because it is non-cloneable! \
Field type is: {}",
dest,
value.type_name()
value.type_info_ref().type_name
);
}
} else {
+2 -2
View File
@@ -3548,13 +3548,13 @@ impl SceneGraph for UserInterface {
fn actual_type_name(&self, handle: Handle<Self::Node>) -> Result<&'static str, PoolError> {
self.nodes
.try_borrow(handle)
.map(|n| Reflect::type_name(n.0.deref()))
.map(|n| n.0.deref().type_info_ref().type_name)
}
fn derived_type_ids(&self, handle: Handle<Self::Node>) -> Result<Vec<TypeId>, PoolError> {
self.nodes
.try_borrow(handle)
.map(|n| n.0.query_derived_types().to_vec())
.map(|n| n.0.type_info_ref().derived_types.to_vec())
}
#[inline]
+18 -24
View File
@@ -31,6 +31,7 @@ use crate::{
use fyrox_graph::SceneGraphNode;
use fyrox_resource::{untyped::UntypedResource, Resource};
use std::any::type_name;
use std::{
any::TypeId,
fmt::{Debug, Formatter},
@@ -265,30 +266,31 @@ impl Visit for UiNode {
}
impl Reflect for UiNode {
fn source_path() -> &'static str {
file!()
fn type_info() -> TypeInfo {
TypeInfo {
source_path: file!(),
type_name: type_name::<Self>(),
assembly_name: env!("CARGO_PKG_NAME"),
doc_comment: "",
derived_types: &[],
}
}
fn derived_types() -> &'static [TypeId] {
&[]
fn type_info_ref(&self) -> TypeInfo {
let inner_type_info = self.deref().type_info_ref();
TypeInfo {
source_path: inner_type_info.source_path,
type_name: inner_type_info.type_name,
assembly_name: inner_type_info.assembly_name,
doc_comment: inner_type_info.doc_comment,
derived_types: inner_type_info.derived_types,
}
}
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
Some(Box::new(self.clone()))
}
fn query_derived_types(&self) -> &'static [TypeId] {
Self::derived_types()
}
fn type_name(&self) -> &'static str {
Reflect::type_name(self.0.deref())
}
fn doc(&self) -> &'static str {
self.0.deref().doc()
}
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
self.0.deref().fields_ref(func)
}
@@ -321,14 +323,6 @@ impl Reflect for UiNode {
self.0.deref_mut().set(value)
}
fn assembly_name(&self) -> &'static str {
self.0.deref().assembly_name()
}
fn type_assembly_name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn field_direct_ref(&self, index: usize) -> Option<FieldRef> {
self.0.deref().field_direct_ref(index)
}
+2 -2
View File
@@ -169,7 +169,7 @@ impl UserInterfaceTestingExtension for UserInterface {
while let Some(msg) = self.poll_message() {
if self.visual_debug {
if let Ok(widget) = self.try_get(msg.destination()) {
let ty = Reflect::type_name(widget);
let ty = widget.type_info_ref().type_name;
info!("[{ty}]{msg:?}");
}
}
@@ -183,7 +183,7 @@ impl UserInterfaceTestingExtension for UserInterface {
while let Some(msg) = self.poll_message() {
if self.visual_debug {
if let Ok(widget) = self.try_get(msg.destination()) {
let ty = Reflect::type_name(widget);
let ty = widget.type_info_ref().type_name;
info!("[{ty}]{msg:?}");
}
}