Skip to content
4 changes: 2 additions & 2 deletions benches/benches/bevy_reflect/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,14 @@ fn concrete_struct_type_info(criterion: &mut Criterion) {
BenchmarkId::new("NonGeneric", field_count),
&standard,
|bencher, s| {
bencher.iter(|| black_box(s.get_type_info()));
bencher.iter(|| black_box(s.get_represented_type_info()));
},
);
group.bench_with_input(
BenchmarkId::new("Generic", field_count),
&generic,
|bencher, s| {
bencher.iter(|| black_box(s.get_type_info()));
bencher.iter(|| black_box(s.get_represented_type_info()));
},
);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream {
}

#[inline]
fn get_type_info(&self) -> &'static #bevy_reflect_path::TypeInfo {
<Self as #bevy_reflect_path::Typed>::type_info()
fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
}

#[inline]
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {

fn clone_dynamic(&self) -> #bevy_reflect_path::DynamicStruct {
let mut dynamic: #bevy_reflect_path::DynamicStruct = #FQDefault::default();
dynamic.set_name(::std::string::ToString::to_string(#bevy_reflect_path::Reflect::type_name(self)));
dynamic.set_represented_type(#bevy_reflect_path::Reflect::get_represented_type_info(self));
#(dynamic.insert_boxed(#field_names, #bevy_reflect_path::Reflect::clone_value(&self.#field_idents));)*
dynamic
}
Expand All @@ -164,8 +164,8 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {
}

#[inline]
fn get_type_info(&self) -> &'static #bevy_reflect_path::TypeInfo {
<Self as #bevy_reflect_path::Typed>::type_info()
fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
}

#[inline]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream {

fn clone_dynamic(&self) -> #bevy_reflect_path::DynamicTupleStruct {
let mut dynamic: #bevy_reflect_path::DynamicTupleStruct = #FQDefault::default();
dynamic.set_name(::std::string::ToString::to_string(#bevy_reflect_path::Reflect::type_name(self)));
dynamic.set_represented_type(#bevy_reflect_path::Reflect::get_represented_type_info(self));
#(dynamic.insert_boxed(#bevy_reflect_path::Reflect::clone_value(&self.#field_idents));)*
dynamic
}
Expand All @@ -135,8 +135,8 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream {
}

#[inline]
fn get_type_info(&self) -> &'static #bevy_reflect_path::TypeInfo {
<Self as #bevy_reflect_path::Typed>::type_info()
fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
}

#[inline]
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream {
}

#[inline]
fn get_type_info(&self) -> &'static #bevy_reflect_path::TypeInfo {
<Self as #bevy_reflect_path::Typed>::type_info()
fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
}

#[inline]
Expand Down
58 changes: 32 additions & 26 deletions crates/bevy_reflect/src/array.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use crate::{
utility::{reflect_hasher, NonGenericTypeInfoCell},
DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed,
};
use crate::{utility::reflect_hasher, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo};
use std::{
any::{Any, TypeId},
fmt::Debug,
Expand Down Expand Up @@ -67,7 +64,7 @@ pub trait Array: Reflect {
/// Clones the list, producing a [`DynamicArray`].
fn clone_dynamic(&self) -> DynamicArray {
DynamicArray {
name: self.type_name().to_string(),
represented_type: self.get_represented_type_info(),
values: self.iter().map(|value| value.clone_value()).collect(),
}
}
Expand Down Expand Up @@ -167,22 +164,22 @@ impl ArrayInfo {
/// [`DynamicList`]: crate::DynamicList
#[derive(Debug)]
pub struct DynamicArray {
pub(crate) name: String,
pub(crate) represented_type: Option<&'static TypeInfo>,
pub(crate) values: Box<[Box<dyn Reflect>]>,
}

impl DynamicArray {
#[inline]
pub fn new(values: Box<[Box<dyn Reflect>]>) -> Self {
Self {
name: String::default(),
represented_type: None,
values,
}
}

pub fn from_vec<T: Reflect>(values: Vec<T>) -> Self {
Self {
name: String::default(),
represented_type: None,
values: values
.into_iter()
.map(|field| Box::new(field) as Box<dyn Reflect>)
Expand All @@ -191,26 +188,37 @@ impl DynamicArray {
}
}

#[inline]
pub fn name(&self) -> &str {
&self.name
}
/// Sets the [type] to be represented by this `DynamicArray`.
///
/// # Panics
///
/// Panics if the given [type] is not a [`TypeInfo::Array`].
///
/// [type]: TypeInfo
pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
if let Some(represented_type) = represented_type {
assert!(
matches!(represented_type, TypeInfo::Array(_)),
"expected TypeInfo::Array but received: {:?}",
represented_type
);
}

#[inline]
pub fn set_name(&mut self, name: String) {
self.name = name;
self.represented_type = represented_type;
}
}

impl Reflect for DynamicArray {
#[inline]
fn type_name(&self) -> &str {
self.name.as_str()
self.represented_type
.map(|info| info.type_name())
.unwrap_or_else(|| std::any::type_name::<Self>())
}

#[inline]
fn get_type_info(&self) -> &'static TypeInfo {
<Self as Typed>::type_info()
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
self.represented_type
}

#[inline]
Expand Down Expand Up @@ -281,6 +289,11 @@ impl Reflect for DynamicArray {
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
array_partial_eq(self, value)
}

#[inline]
fn is_dynamic(&self) -> bool {
true
}
}

impl Array for DynamicArray {
Expand Down Expand Up @@ -312,7 +325,7 @@ impl Array for DynamicArray {
#[inline]
fn clone_dynamic(&self) -> DynamicArray {
DynamicArray {
name: self.name.clone(),
represented_type: self.represented_type,
values: self
.values
.iter()
Expand All @@ -322,13 +335,6 @@ impl Array for DynamicArray {
}
}

impl Typed for DynamicArray {
fn type_info() -> &'static TypeInfo {
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
CELL.get_or_set(|| TypeInfo::Dynamic(DynamicInfo::new::<Self>()))
}
}

/// An iterator over an [`Array`].
pub struct ArrayIter<'a> {
array: &'a dyn Array,
Expand Down
77 changes: 36 additions & 41 deletions crates/bevy_reflect/src/enums/dynamic_enum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::utility::NonGenericTypeInfoCell;
use crate::{
enum_debug, enum_hash, enum_partial_eq, DynamicInfo, DynamicStruct, DynamicTuple, Enum,
Reflect, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, Typed,
VariantFieldIter, VariantType,
enum_debug, enum_hash, enum_partial_eq, DynamicStruct, DynamicTuple, Enum, Reflect, ReflectMut,
ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, VariantFieldIter, VariantType,
};
use std::any::Any;
use std::fmt::Formatter;
Expand Down Expand Up @@ -58,7 +56,6 @@ impl From<()> for DynamicVariant {
///
/// // Create a DynamicEnum to represent the new value
/// let mut dyn_enum = DynamicEnum::new(
/// Reflect::type_name(&value),
/// "None",
/// DynamicVariant::Unit
/// );
Expand All @@ -71,7 +68,7 @@ impl From<()> for DynamicVariant {
/// ```
#[derive(Default, Debug)]
pub struct DynamicEnum {
name: String,
represented_type: Option<&'static TypeInfo>,
variant_name: String,
variant_index: usize,
variant: DynamicVariant,
Expand All @@ -82,17 +79,12 @@ impl DynamicEnum {
///
/// # Arguments
///
/// * `name`: The type name of the enum
/// * `variant_name`: The name of the variant to set
/// * `variant`: The variant data
///
pub fn new<I: Into<String>, V: Into<DynamicVariant>>(
name: I,
variant_name: I,
variant: V,
) -> Self {
pub fn new<I: Into<String>, V: Into<DynamicVariant>>(variant_name: I, variant: V) -> Self {
Self {
name: name.into(),
represented_type: None,
variant_index: 0,
variant_name: variant_name.into(),
variant: variant.into(),
Expand All @@ -103,33 +95,40 @@ impl DynamicEnum {
///
/// # Arguments
///
/// * `name`: The type name of the enum
/// * `variant_index`: The index of the variant to set
/// * `variant_name`: The name of the variant to set
/// * `variant`: The variant data
///
pub fn new_with_index<I: Into<String>, V: Into<DynamicVariant>>(
name: I,
variant_index: usize,
variant_name: I,
variant: V,
) -> Self {
Self {
name: name.into(),
represented_type: None,
variant_index,
variant_name: variant_name.into(),
variant: variant.into(),
}
}

/// Returns the type name of the enum.
pub fn name(&self) -> &str {
&self.name
}
/// Sets the [type] to be represented by this `DynamicEnum`.
///
/// # Panics
///
/// Panics if the given [type] is not a [`TypeInfo::Enum`].
///
/// [type]: TypeInfo
pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
if let Some(represented_type) = represented_type {
assert!(
matches!(represented_type, TypeInfo::Enum(_)),
"expected TypeInfo::Enum but received: {:?}",
represented_type
);
}

/// Sets the type name of the enum.
pub fn set_name(&mut self, name: String) {
self.name = name;
self.represented_type = represented_type;
}

/// Set the current enum variant represented by this struct.
Expand All @@ -142,11 +141,11 @@ impl DynamicEnum {
pub fn set_variant_with_index<I: Into<String>, V: Into<DynamicVariant>>(
&mut self,
variant_index: usize,
name: I,
variant_name: I,
variant: V,
) {
self.variant_index = variant_index;
self.variant_name = name.into();
self.variant_name = variant_name.into();
self.variant = variant.into();
}

Expand All @@ -161,9 +160,9 @@ impl DynamicEnum {
///
/// This is functionally the same as [`DynamicEnum::from`] except it takes a reference.
pub fn from_ref<TEnum: Enum>(value: &TEnum) -> Self {
match value.variant_type() {
let type_info = value.get_represented_type_info();
let mut dyn_enum = match value.variant_type() {
VariantType::Unit => DynamicEnum::new_with_index(
value.type_name(),
value.variant_index(),
value.variant_name(),
DynamicVariant::Unit,
Expand All @@ -174,7 +173,6 @@ impl DynamicEnum {
data.insert_boxed(field.value().clone_value());
}
DynamicEnum::new_with_index(
value.type_name(),
value.variant_index(),
value.variant_name(),
DynamicVariant::Tuple(data),
Expand All @@ -187,13 +185,15 @@ impl DynamicEnum {
data.insert_boxed(name, field.value().clone_value());
}
DynamicEnum::new_with_index(
value.type_name(),
value.variant_index(),
value.variant_name(),
DynamicVariant::Struct(data),
)
}
}
};

dyn_enum.set_represented_type(type_info);
dyn_enum
}
}

Expand Down Expand Up @@ -276,7 +276,7 @@ impl Enum for DynamicEnum {

fn clone_dynamic(&self) -> DynamicEnum {
Self {
name: self.name.clone(),
represented_type: self.represented_type,
variant_index: self.variant_index,
variant_name: self.variant_name.clone(),
variant: self.variant.clone(),
Expand All @@ -287,12 +287,14 @@ impl Enum for DynamicEnum {
impl Reflect for DynamicEnum {
#[inline]
fn type_name(&self) -> &str {
&self.name
self.represented_type
.map(|info| info.type_name())
.unwrap_or_default()
}

#[inline]
fn get_type_info(&self) -> &'static TypeInfo {
<Self as Typed>::type_info()
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
self.represented_type
}

#[inline]
Expand Down Expand Up @@ -418,10 +420,3 @@ impl Reflect for DynamicEnum {
write!(f, ")")
}
}

impl Typed for DynamicEnum {
fn type_info() -> &'static TypeInfo {
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
CELL.get_or_set(|| TypeInfo::Dynamic(DynamicInfo::new::<Self>()))
}
}
Loading