bevy_reflect: Replace "value" terminology with "opaque" (#15240)
# Objective Currently, the term "value" in the context of reflection is a bit overloaded. For one, it can be used synonymously with "data" or "variable". An example sentence would be "this function takes a reflected value". However, it is also used to refer to reflected types which are `ReflectKind::Value`. These types are usually either primitives, opaque types, or types that don't fall into any other `ReflectKind` (or perhaps could, but don't due to some limitation/difficulty). An example sentence would be "this function takes a reflected value type". This makes it difficult to write good documentation or other learning material without causing some amount of confusion to readers. Ideally, we'd be able to move away from the `ReflectKind::Value` usage and come up with a better term. ## Solution This PR replaces the terminology of "value" with "opaque" across `bevy_reflect`. This includes in documentation, type names, variant names, and macros. The term "opaque" was chosen because that's essentially how the type is treated within the reflection API. In other words, its internal structure is hidden. All we can do is work with the type itself. ### Primitives While primitives are not technically opaque types, I think it's still clearer to refer to them as "opaque" rather than keep the confusing "value" terminology. We could consider adding another concept for primitives (e.g. `ReflectKind::Primitive`), but I'm not sure that provides a lot of benefit right now. In most circumstances, they'll be treated just like an opaque type. They would also likely use the same macro (or two copies of the same macro but with different names). ## Testing You can test locally by running: ``` cargo test --package bevy_reflect --all-features ``` --- ## Migration Guide The reflection concept of "value type" has been replaced with a clearer "opaque type". The following renames have been made to account for this: - `ReflectKind::Value` → `ReflectKind::Opaque` - `ReflectRef::Value` → `ReflectRef::Opaque` - `ReflectMut::Value` → `ReflectMut::Opaque` - `ReflectOwned::Value` → `ReflectOwned::Opaque` - `TypeInfo::Value` → `TypeInfo::Opaque` - `ValueInfo` → `OpaqueInfo` - `impl_reflect_value!` → `impl_reflect_opaque!` - `impl_from_reflect_value!` → `impl_from_reflect_opaque!` Additionally, declaring your own opaque types no longer uses `#[reflect_value]`. This attribute has been replaced by `#[reflect(opaque)]`: ```rust // BEFORE #[derive(Reflect)] #[reflect_value(Default)] struct MyOpaqueType(u32); // AFTER #[derive(Reflect)] #[reflect(opaque)] #[reflect(Default)] struct MyOpaqueType(u32); ``` Note that the order in which `#[reflect(opaque)]` appears does not matter.
This commit is contained in:
parent
3139b03e74
commit
83356b12c9
@ -48,7 +48,8 @@ use thiserror::Error;
|
|||||||
/// clones internal owned [`AssetPaths`](AssetPath).
|
/// clones internal owned [`AssetPaths`](AssetPath).
|
||||||
/// This also means that you should use [`AssetPath::parse`] in cases where `&str` is the explicit type.
|
/// This also means that you should use [`AssetPath::parse`] in cases where `&str` is the explicit type.
|
||||||
#[derive(Eq, PartialEq, Hash, Clone, Default, Reflect)]
|
#[derive(Eq, PartialEq, Hash, Clone, Default, Reflect)]
|
||||||
#[reflect_value(Debug, PartialEq, Hash, Serialize, Deserialize)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
pub struct AssetPath<'a> {
|
pub struct AssetPath<'a> {
|
||||||
source: AssetSourceId<'a>,
|
source: AssetSourceId<'a>,
|
||||||
path: CowArc<'a, Path>,
|
path: CowArc<'a, Path>,
|
||||||
|
@ -144,10 +144,11 @@ type IdCursor = isize;
|
|||||||
/// [SemVer]: https://semver.org/
|
/// [SemVer]: https://semver.org/
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
|
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
|
||||||
#[cfg_attr(feature = "bevy_reflect", reflect_value(Hash, PartialEq, Debug))]
|
#[cfg_attr(feature = "bevy_reflect", reflect(opaque))]
|
||||||
|
#[cfg_attr(feature = "bevy_reflect", reflect(Hash, PartialEq, Debug))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
all(feature = "bevy_reflect", feature = "serialize"),
|
all(feature = "bevy_reflect", feature = "serialize"),
|
||||||
reflect_value(Serialize, Deserialize)
|
reflect(Serialize, Deserialize)
|
||||||
)]
|
)]
|
||||||
// Alignment repr necessary to allow LLVM to better output
|
// Alignment repr necessary to allow LLVM to better output
|
||||||
// optimised codegen for `to_bits`, `PartialEq` and `Ord`.
|
// optimised codegen for `to_bits`, `PartialEq` and `Ord`.
|
||||||
|
@ -19,7 +19,8 @@ pub(crate) mod masks;
|
|||||||
/// entity kinds.
|
/// entity kinds.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
|
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
|
||||||
#[cfg_attr(feature = "bevy_reflect", reflect_value(Debug, Hash, PartialEq))]
|
#[cfg_attr(feature = "bevy_reflect", reflect(opaque))]
|
||||||
|
#[cfg_attr(feature = "bevy_reflect", reflect(Debug, Hash, PartialEq))]
|
||||||
// Alignment repr necessary to allow LLVM to better output
|
// Alignment repr necessary to allow LLVM to better output
|
||||||
// optimised codegen for `to_bits`, `PartialEq` and `Ord`.
|
// optimised codegen for `to_bits`, `PartialEq` and `Ord`.
|
||||||
#[repr(C, align(8))]
|
#[repr(C, align(8))]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//! A container attribute is an attribute which applies to an entire struct or enum
|
//! A container attribute is an attribute which applies to an entire struct or enum
|
||||||
//! as opposed to a particular field or variant. An example of such an attribute is
|
//! as opposed to a particular field or variant. An example of such an attribute is
|
||||||
//! the derive helper attribute for `Reflect`, which looks like:
|
//! the derive helper attribute for `Reflect`, which looks like:
|
||||||
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
|
//! `#[reflect(PartialEq, Default, ...)]`.
|
||||||
|
|
||||||
use crate::attribute_parser::terminated_parser;
|
use crate::attribute_parser::terminated_parser;
|
||||||
use crate::custom_attributes::CustomAttributes;
|
use crate::custom_attributes::CustomAttributes;
|
||||||
@ -23,6 +23,7 @@ mod kw {
|
|||||||
syn::custom_keyword!(PartialEq);
|
syn::custom_keyword!(PartialEq);
|
||||||
syn::custom_keyword!(Hash);
|
syn::custom_keyword!(Hash);
|
||||||
syn::custom_keyword!(no_field_bounds);
|
syn::custom_keyword!(no_field_bounds);
|
||||||
|
syn::custom_keyword!(opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The "special" trait idents that are used internally for reflection.
|
// The "special" trait idents that are used internally for reflection.
|
||||||
@ -188,6 +189,7 @@ pub(crate) struct ContainerAttributes {
|
|||||||
custom_where: Option<WhereClause>,
|
custom_where: Option<WhereClause>,
|
||||||
no_field_bounds: bool,
|
no_field_bounds: bool,
|
||||||
custom_attributes: CustomAttributes,
|
custom_attributes: CustomAttributes,
|
||||||
|
is_opaque: bool,
|
||||||
idents: Vec<Ident>,
|
idents: Vec<Ident>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +238,8 @@ impl ContainerAttributes {
|
|||||||
self.parse_from_reflect(input, trait_)
|
self.parse_from_reflect(input, trait_)
|
||||||
} else if lookahead.peek(kw::type_path) {
|
} else if lookahead.peek(kw::type_path) {
|
||||||
self.parse_type_path(input, trait_)
|
self.parse_type_path(input, trait_)
|
||||||
|
} else if lookahead.peek(kw::opaque) {
|
||||||
|
self.parse_opaque(input)
|
||||||
} else if lookahead.peek(kw::no_field_bounds) {
|
} else if lookahead.peek(kw::no_field_bounds) {
|
||||||
self.parse_no_field_bounds(input)
|
self.parse_no_field_bounds(input)
|
||||||
} else if lookahead.peek(kw::Debug) {
|
} else if lookahead.peek(kw::Debug) {
|
||||||
@ -336,6 +340,16 @@ impl ContainerAttributes {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse `opaque` attribute.
|
||||||
|
///
|
||||||
|
/// Examples:
|
||||||
|
/// - `#[reflect(opaque)]`
|
||||||
|
fn parse_opaque(&mut self, input: ParseStream) -> syn::Result<()> {
|
||||||
|
input.parse::<kw::opaque>()?;
|
||||||
|
self.is_opaque = true;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse `no_field_bounds` attribute.
|
/// Parse `no_field_bounds` attribute.
|
||||||
///
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
@ -528,6 +542,11 @@ impl ContainerAttributes {
|
|||||||
pub fn no_field_bounds(&self) -> bool {
|
pub fn no_field_bounds(&self) -> bool {
|
||||||
self.no_field_bounds
|
self.no_field_bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `opaque` attribute was found on this type.
|
||||||
|
pub fn is_opaque(&self) -> bool {
|
||||||
|
self.is_opaque
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an identifier to a vector of identifiers if it is not already present.
|
/// Adds an identifier to a vector of identifiers if it is not already present.
|
||||||
|
@ -12,10 +12,7 @@ use syn::token::Comma;
|
|||||||
|
|
||||||
use crate::remote::RemoteType;
|
use crate::remote::RemoteType;
|
||||||
use crate::serialization::SerializationDataDef;
|
use crate::serialization::SerializationDataDef;
|
||||||
use crate::{
|
use crate::{REFLECT_ATTRIBUTE_NAME, TYPE_NAME_ATTRIBUTE_NAME, TYPE_PATH_ATTRIBUTE_NAME};
|
||||||
REFLECT_ATTRIBUTE_NAME, REFLECT_VALUE_ATTRIBUTE_NAME, TYPE_NAME_ATTRIBUTE_NAME,
|
|
||||||
TYPE_PATH_ATTRIBUTE_NAME,
|
|
||||||
};
|
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
@ -28,7 +25,7 @@ pub(crate) enum ReflectDerive<'a> {
|
|||||||
TupleStruct(ReflectStruct<'a>),
|
TupleStruct(ReflectStruct<'a>),
|
||||||
UnitStruct(ReflectStruct<'a>),
|
UnitStruct(ReflectStruct<'a>),
|
||||||
Enum(ReflectEnum<'a>),
|
Enum(ReflectEnum<'a>),
|
||||||
Value(ReflectMeta<'a>),
|
Opaque(ReflectMeta<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata present on all reflected types, including name, generics, and attributes.
|
/// Metadata present on all reflected types, including name, generics, and attributes.
|
||||||
@ -135,15 +132,6 @@ pub(crate) enum EnumVariantFields<'a> {
|
|||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The method in which the type should be reflected.
|
|
||||||
#[derive(PartialEq, Eq)]
|
|
||||||
enum ReflectMode {
|
|
||||||
/// Reflect the type normally, providing information about all fields/variants.
|
|
||||||
Normal,
|
|
||||||
/// Reflect the type as a value.
|
|
||||||
Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How the macro was invoked.
|
/// How the macro was invoked.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub(crate) enum ReflectImplSource {
|
pub(crate) enum ReflectImplSource {
|
||||||
@ -192,8 +180,6 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
provenance: ReflectProvenance,
|
provenance: ReflectProvenance,
|
||||||
) -> Result<Self, syn::Error> {
|
) -> Result<Self, syn::Error> {
|
||||||
let mut container_attributes = ContainerAttributes::default();
|
let mut container_attributes = ContainerAttributes::default();
|
||||||
// Should indicate whether `#[reflect_value]` was used.
|
|
||||||
let mut reflect_mode = None;
|
|
||||||
// Should indicate whether `#[type_path = "..."]` was used.
|
// Should indicate whether `#[type_path = "..."]` was used.
|
||||||
let mut custom_path: Option<Path> = None;
|
let mut custom_path: Option<Path> = None;
|
||||||
// Should indicate whether `#[type_name = "..."]` was used.
|
// Should indicate whether `#[type_name = "..."]` was used.
|
||||||
@ -205,37 +191,8 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
for attribute in &input.attrs {
|
for attribute in &input.attrs {
|
||||||
match &attribute.meta {
|
match &attribute.meta {
|
||||||
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_ATTRIBUTE_NAME) => {
|
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_ATTRIBUTE_NAME) => {
|
||||||
if !matches!(reflect_mode, None | Some(ReflectMode::Normal)) {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
meta_list.span(),
|
|
||||||
format_args!("cannot use both `#[{REFLECT_ATTRIBUTE_NAME}]` and `#[{REFLECT_VALUE_ATTRIBUTE_NAME}]`"),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
reflect_mode = Some(ReflectMode::Normal);
|
|
||||||
container_attributes.parse_meta_list(meta_list, provenance.trait_)?;
|
container_attributes.parse_meta_list(meta_list, provenance.trait_)?;
|
||||||
}
|
}
|
||||||
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
|
||||||
if !matches!(reflect_mode, None | Some(ReflectMode::Value)) {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
meta_list.span(),
|
|
||||||
format_args!("cannot use both `#[{REFLECT_ATTRIBUTE_NAME}]` and `#[{REFLECT_VALUE_ATTRIBUTE_NAME}]`"),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
reflect_mode = Some(ReflectMode::Value);
|
|
||||||
container_attributes.parse_meta_list(meta_list, provenance.trait_)?;
|
|
||||||
}
|
|
||||||
Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
|
||||||
if !matches!(reflect_mode, None | Some(ReflectMode::Value)) {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
path.span(),
|
|
||||||
format_args!("cannot use both `#[{REFLECT_ATTRIBUTE_NAME}]` and `#[{REFLECT_VALUE_ATTRIBUTE_NAME}]`"),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
reflect_mode = Some(ReflectMode::Value);
|
|
||||||
}
|
|
||||||
Meta::NameValue(pair) if pair.path.is_ident(TYPE_PATH_ATTRIBUTE_NAME) => {
|
Meta::NameValue(pair) if pair.path.is_ident(TYPE_PATH_ATTRIBUTE_NAME) => {
|
||||||
let syn::Expr::Lit(syn::ExprLit {
|
let syn::Expr::Lit(syn::ExprLit {
|
||||||
lit: syn::Lit::Str(lit),
|
lit: syn::Lit::Str(lit),
|
||||||
@ -315,11 +272,8 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
let meta = meta.with_docs(doc);
|
let meta = meta.with_docs(doc);
|
||||||
|
|
||||||
// Use normal reflection if unspecified
|
if meta.attrs().is_opaque() {
|
||||||
let reflect_mode = reflect_mode.unwrap_or(ReflectMode::Normal);
|
return Ok(Self::Opaque(meta));
|
||||||
|
|
||||||
if reflect_mode == ReflectMode::Value {
|
|
||||||
return Ok(Self::Value(meta));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return match &input.data {
|
return match &input.data {
|
||||||
@ -354,7 +308,7 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics when called on [`ReflectDerive::Value`].
|
/// Panics when called on [`ReflectDerive::Opaque`].
|
||||||
pub fn set_remote(&mut self, remote_ty: Option<RemoteType<'a>>) {
|
pub fn set_remote(&mut self, remote_ty: Option<RemoteType<'a>>) {
|
||||||
match self {
|
match self {
|
||||||
Self::Struct(data) | Self::TupleStruct(data) | Self::UnitStruct(data) => {
|
Self::Struct(data) | Self::TupleStruct(data) | Self::UnitStruct(data) => {
|
||||||
@ -363,7 +317,7 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
Self::Enum(data) => {
|
Self::Enum(data) => {
|
||||||
data.meta.remote_ty = remote_ty;
|
data.meta.remote_ty = remote_ty;
|
||||||
}
|
}
|
||||||
Self::Value(meta) => {
|
Self::Opaque(meta) => {
|
||||||
meta.remote_ty = remote_ty;
|
meta.remote_ty = remote_ty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +330,7 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
data.meta.remote_ty()
|
data.meta.remote_ty()
|
||||||
}
|
}
|
||||||
Self::Enum(data) => data.meta.remote_ty(),
|
Self::Enum(data) => data.meta.remote_ty(),
|
||||||
Self::Value(meta) => meta.remote_ty(),
|
Self::Opaque(meta) => meta.remote_ty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +339,7 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
match self {
|
match self {
|
||||||
Self::Struct(data) | Self::TupleStruct(data) | Self::UnitStruct(data) => data.meta(),
|
Self::Struct(data) | Self::TupleStruct(data) | Self::UnitStruct(data) => data.meta(),
|
||||||
Self::Enum(data) => data.meta(),
|
Self::Enum(data) => data.meta(),
|
||||||
Self::Value(meta) => meta,
|
Self::Opaque(meta) => meta,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +349,7 @@ impl<'a> ReflectDerive<'a> {
|
|||||||
data.where_clause_options()
|
data.where_clause_options()
|
||||||
}
|
}
|
||||||
Self::Enum(data) => data.where_clause_options(),
|
Self::Enum(data) => data.where_clause_options(),
|
||||||
Self::Value(meta) => WhereClauseOptions::new(meta),
|
Self::Opaque(meta) => WhereClauseOptions::new(meta),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::
|
|||||||
impl_struct_internal(reflect_struct, true)
|
impl_struct_internal(reflect_struct, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
||||||
let type_path = meta.type_path();
|
let type_path = meta.type_path();
|
||||||
let bevy_reflect_path = meta.bevy_reflect_path();
|
let bevy_reflect_path = meta.bevy_reflect_path();
|
||||||
let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
|
||||||
|
@ -3,17 +3,17 @@ mod common;
|
|||||||
mod enums;
|
mod enums;
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
mod func;
|
mod func;
|
||||||
|
mod opaque;
|
||||||
mod structs;
|
mod structs;
|
||||||
mod tuple_structs;
|
mod tuple_structs;
|
||||||
mod typed;
|
mod typed;
|
||||||
mod values;
|
|
||||||
|
|
||||||
pub(crate) use assertions::impl_assertions;
|
pub(crate) use assertions::impl_assertions;
|
||||||
pub(crate) use common::{common_partial_reflect_methods, impl_full_reflect};
|
pub(crate) use common::{common_partial_reflect_methods, impl_full_reflect};
|
||||||
pub(crate) use enums::impl_enum;
|
pub(crate) use enums::impl_enum;
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
pub(crate) use func::impl_function_traits;
|
pub(crate) use func::impl_function_traits;
|
||||||
|
pub(crate) use opaque::impl_opaque;
|
||||||
pub(crate) use structs::impl_struct;
|
pub(crate) use structs::impl_struct;
|
||||||
pub(crate) use tuple_structs::impl_tuple_struct;
|
pub(crate) use tuple_structs::impl_tuple_struct;
|
||||||
pub(crate) use typed::{impl_type_path, impl_typed};
|
pub(crate) use typed::{impl_type_path, impl_typed};
|
||||||
pub(crate) use values::impl_value;
|
|
||||||
|
@ -5,7 +5,7 @@ use bevy_macro_utils::fq_std::{FQBox, FQClone, FQOption, FQResult};
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
/// Implements `GetTypeRegistration` and `Reflect` for the given type data.
|
/// Implements `GetTypeRegistration` and `Reflect` for the given type data.
|
||||||
pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
||||||
let bevy_reflect_path = meta.bevy_reflect_path();
|
let bevy_reflect_path = meta.bevy_reflect_path();
|
||||||
let type_path = meta.type_path();
|
let type_path = meta.type_path();
|
||||||
|
|
||||||
@ -22,8 +22,8 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
|||||||
meta,
|
meta,
|
||||||
&where_clause_options,
|
&where_clause_options,
|
||||||
quote! {
|
quote! {
|
||||||
let info = #bevy_reflect_path::ValueInfo::new::<Self>() #with_docs;
|
let info = #bevy_reflect_path::OpaqueInfo::new::<Self>() #with_docs;
|
||||||
#bevy_reflect_path::TypeInfo::Value(info)
|
#bevy_reflect_path::TypeInfo::Opaque(info)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -96,22 +96,22 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
|
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
|
||||||
#bevy_reflect_path::ReflectKind::Value
|
#bevy_reflect_path::ReflectKind::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
|
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
|
||||||
#bevy_reflect_path::ReflectRef::Value(self)
|
#bevy_reflect_path::ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_mut(&mut self) -> #bevy_reflect_path::ReflectMut {
|
fn reflect_mut(&mut self) -> #bevy_reflect_path::ReflectMut {
|
||||||
#bevy_reflect_path::ReflectMut::Value(self)
|
#bevy_reflect_path::ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned {
|
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned {
|
||||||
#bevy_reflect_path::ReflectOwned::Value(self)
|
#bevy_reflect_path::ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#common_methods
|
#common_methods
|
@ -28,7 +28,7 @@ mod from_reflect;
|
|||||||
mod ident;
|
mod ident;
|
||||||
mod impls;
|
mod impls;
|
||||||
mod meta;
|
mod meta;
|
||||||
mod reflect_value;
|
mod reflect_opaque;
|
||||||
mod registration;
|
mod registration;
|
||||||
mod remote;
|
mod remote;
|
||||||
mod result_sifter;
|
mod result_sifter;
|
||||||
@ -44,12 +44,11 @@ use container_attributes::ContainerAttributes;
|
|||||||
use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
|
use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use reflect_value::ReflectValueDef;
|
use reflect_opaque::ReflectOpaqueDef;
|
||||||
use syn::{parse_macro_input, DeriveInput};
|
use syn::{parse_macro_input, DeriveInput};
|
||||||
use type_path::NamedTypePathDef;
|
use type_path::NamedTypePathDef;
|
||||||
|
|
||||||
pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";
|
pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";
|
||||||
pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
|
|
||||||
pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
|
pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
|
||||||
pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
|
pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
|
||||||
|
|
||||||
@ -96,10 +95,10 @@ fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStre
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ReflectDerive::Value(meta) => (
|
ReflectDerive::Opaque(meta) => (
|
||||||
impls::impl_value(&meta),
|
impls::impl_opaque(&meta),
|
||||||
if meta.from_reflect().should_auto_derive() {
|
if meta.from_reflect().should_auto_derive() {
|
||||||
Some(from_reflect::impl_value(&meta))
|
Some(from_reflect::impl_opaque(&meta))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
@ -178,10 +177,10 @@ fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStre
|
|||||||
/// a base value using its [`Default`] implementation avoiding issues with ignored fields
|
/// a base value using its [`Default`] implementation avoiding issues with ignored fields
|
||||||
/// (for structs and tuple structs only).
|
/// (for structs and tuple structs only).
|
||||||
///
|
///
|
||||||
/// ## `#[reflect_value]`
|
/// ## `#[reflect(opaque)]`
|
||||||
///
|
///
|
||||||
/// The `#[reflect_value]` attribute (which may also take the form `#[reflect_value(Ident)]`),
|
/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,
|
||||||
/// denotes that the item should implement `Reflect` as though it were a base value type.
|
/// hiding its structure and fields from the reflection API.
|
||||||
/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.
|
/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.
|
||||||
///
|
///
|
||||||
/// Furthermore, it requires that the type implements [`Clone`].
|
/// Furthermore, it requires that the type implements [`Clone`].
|
||||||
@ -369,7 +368,7 @@ fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStre
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`reflect_trait`]: macro@reflect_trait
|
/// [`reflect_trait`]: macro@reflect_trait
|
||||||
#[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))]
|
#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]
|
||||||
pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
|
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
|
||||||
@ -422,7 +421,7 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),
|
ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),
|
||||||
ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),
|
ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),
|
||||||
ReflectDerive::Value(meta) => from_reflect::impl_value(&meta),
|
ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
@ -610,10 +609,10 @@ pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
/// A macro used to generate reflection trait implementations for the given type.
|
/// A macro used to generate reflection trait implementations for the given type.
|
||||||
///
|
///
|
||||||
/// This is functionally the same as [deriving `Reflect`] using the `#[reflect_value]` container attribute.
|
/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.
|
||||||
///
|
///
|
||||||
/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits
|
/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits
|
||||||
/// on primitives and other Rust types internally.
|
/// on primitives and other opaque types internally.
|
||||||
///
|
///
|
||||||
/// Since this macro also implements `TypePath`, the type path must be explicit.
|
/// Since this macro also implements `TypePath`, the type path must be explicit.
|
||||||
/// See [`impl_type_path!`] for the exact syntax.
|
/// See [`impl_type_path!`] for the exact syntax.
|
||||||
@ -623,26 +622,26 @@ pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
/// Types can be passed with or without registering type data:
|
/// Types can be passed with or without registering type data:
|
||||||
///
|
///
|
||||||
/// ```ignore (bevy_reflect is not accessible from this crate)
|
/// ```ignore (bevy_reflect is not accessible from this crate)
|
||||||
/// impl_reflect_value!(my_crate::Foo);
|
/// impl_reflect_opaque!(my_crate::Foo);
|
||||||
/// impl_reflect_value!(my_crate::Bar(Debug, Default, Serialize, Deserialize));
|
/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Generic types can also specify their parameters and bounds:
|
/// Generic types can also specify their parameters and bounds:
|
||||||
///
|
///
|
||||||
/// ```ignore (bevy_reflect is not accessible from this crate)
|
/// ```ignore (bevy_reflect is not accessible from this crate)
|
||||||
/// impl_reflect_value!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));
|
/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Custom type paths can be specified:
|
/// Custom type paths can be specified:
|
||||||
///
|
///
|
||||||
/// ```ignore (bevy_reflect is not accessible from this crate)
|
/// ```ignore (bevy_reflect is not accessible from this crate)
|
||||||
/// impl_reflect_value!((in not_my_crate as NotFoo) Foo(Debug, Default));
|
/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [deriving `Reflect`]: Reflect
|
/// [deriving `Reflect`]: Reflect
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {
|
||||||
let def = parse_macro_input!(input with ReflectValueDef::parse_reflect);
|
let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);
|
||||||
|
|
||||||
let default_name = &def.type_path.segments.last().unwrap().ident;
|
let default_name = &def.type_path.segments.last().unwrap().ident;
|
||||||
let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
|
let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
|
||||||
@ -660,8 +659,8 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
|||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));
|
let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));
|
||||||
|
|
||||||
let reflect_impls = impls::impl_value(&meta);
|
let reflect_impls = impls::impl_opaque(&meta);
|
||||||
let from_reflect_impl = from_reflect::impl_value(&meta);
|
let from_reflect_impl = from_reflect::impl_opaque(&meta);
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
const _: () = {
|
const _: () = {
|
||||||
@ -674,8 +673,8 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
|||||||
/// A replacement for `#[derive(Reflect)]` to be used with foreign types which
|
/// A replacement for `#[derive(Reflect)]` to be used with foreign types which
|
||||||
/// the definitions of cannot be altered.
|
/// the definitions of cannot be altered.
|
||||||
///
|
///
|
||||||
/// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`]
|
/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]
|
||||||
/// which implement foreign types as Value types. Note that there is no `impl_from_reflect`,
|
/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,
|
||||||
/// as this macro will do the job of both. This macro implements them using one of the reflect
|
/// as this macro will do the job of both. This macro implements them using one of the reflect
|
||||||
/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
|
/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
|
||||||
/// which have greater functionality. The type being reflected must be in scope, as you cannot
|
/// which have greater functionality. The type being reflected must be in scope, as you cannot
|
||||||
@ -713,26 +712,26 @@ pub fn impl_reflect(input: TokenStream) -> TokenStream {
|
|||||||
/// A macro used to generate a `FromReflect` trait implementation for the given type.
|
/// A macro used to generate a `FromReflect` trait implementation for the given type.
|
||||||
///
|
///
|
||||||
/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using
|
/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using
|
||||||
/// the `#[reflect_value]` container attribute.
|
/// the `#[reflect(opaque)]` container attribute.
|
||||||
///
|
///
|
||||||
/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on
|
/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on
|
||||||
/// primitives and other Rust types internally.
|
/// primitives and other opaque types internally.
|
||||||
///
|
///
|
||||||
/// Please note that this macro will not work with any type that [derives `Reflect`] normally
|
/// Please note that this macro will not work with any type that [derives `Reflect`] normally
|
||||||
/// or makes use of the [`impl_reflect_value!`] macro, as those macros also implement `FromReflect`
|
/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`
|
||||||
/// by default.
|
/// by default.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore (bevy_reflect is not accessible from this crate)
|
/// ```ignore (bevy_reflect is not accessible from this crate)
|
||||||
/// impl_from_reflect_value!(foo<T1, T2: Baz> where T1: Bar);
|
/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [deriving `FromReflect`]: FromReflect
|
/// [deriving `FromReflect`]: FromReflect
|
||||||
/// [derives `Reflect`]: Reflect
|
/// [derives `Reflect`]: Reflect
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream {
|
pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {
|
||||||
let def = parse_macro_input!(input with ReflectValueDef::parse_from_reflect);
|
let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);
|
||||||
|
|
||||||
let default_name = &def.type_path.segments.last().unwrap().ident;
|
let default_name = &def.type_path.segments.last().unwrap().ident;
|
||||||
let type_path = if def.type_path.leading_colon.is_none()
|
let type_path = if def.type_path.leading_colon.is_none()
|
||||||
@ -749,7 +748,7 @@ pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let from_reflect_impl =
|
let from_reflect_impl =
|
||||||
from_reflect::impl_value(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));
|
from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
const _: () = {
|
const _: () = {
|
||||||
|
@ -5,9 +5,7 @@ use syn::parse::ParseStream;
|
|||||||
use syn::token::Paren;
|
use syn::token::Paren;
|
||||||
use syn::{parenthesized, Attribute, Generics, Path};
|
use syn::{parenthesized, Attribute, Generics, Path};
|
||||||
|
|
||||||
/// A struct used to define a simple reflected value type (such as primitives).
|
/// A struct used to define a simple reflection-opaque types (including primitives).
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
///
|
||||||
/// This takes the form:
|
/// This takes the form:
|
||||||
///
|
///
|
||||||
@ -21,10 +19,10 @@ use syn::{parenthesized, Attribute, Generics, Path};
|
|||||||
/// // With generics and where clause
|
/// // With generics and where clause
|
||||||
/// ::my_crate::foo::Bar<T1, T2> where T1: Bar (TraitA, TraitB)
|
/// ::my_crate::foo::Bar<T1, T2> where T1: Bar (TraitA, TraitB)
|
||||||
///
|
///
|
||||||
/// // With a custom path (not with impl_from_reflect_value)
|
/// // With a custom path (not with impl_from_reflect_opaque)
|
||||||
/// (in my_crate::bar) Bar(TraitA, TraitB)
|
/// (in my_crate::bar) Bar(TraitA, TraitB)
|
||||||
/// ```
|
/// ```
|
||||||
pub(crate) struct ReflectValueDef {
|
pub(crate) struct ReflectOpaqueDef {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
not(feature = "documentation"),
|
not(feature = "documentation"),
|
||||||
expect(
|
expect(
|
||||||
@ -39,7 +37,7 @@ pub(crate) struct ReflectValueDef {
|
|||||||
pub custom_path: Option<CustomPathDef>,
|
pub custom_path: Option<CustomPathDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReflectValueDef {
|
impl ReflectOpaqueDef {
|
||||||
pub fn parse_reflect(input: ParseStream) -> syn::Result<Self> {
|
pub fn parse_reflect(input: ParseStream) -> syn::Result<Self> {
|
||||||
Self::parse(input, ReflectTraitToImpl::Reflect)
|
Self::parse(input, ReflectTraitToImpl::Reflect)
|
||||||
}
|
}
|
||||||
@ -67,7 +65,7 @@ impl ReflectValueDef {
|
|||||||
attrs
|
attrs
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(ReflectValueDef {
|
Ok(Self {
|
||||||
attrs,
|
attrs,
|
||||||
type_path,
|
type_path,
|
||||||
generics,
|
generics,
|
@ -1,9 +1,7 @@
|
|||||||
use crate::derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl};
|
use crate::derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl};
|
||||||
use crate::ident::ident_or_index;
|
use crate::ident::ident_or_index;
|
||||||
use crate::impls::impl_assertions;
|
use crate::impls::impl_assertions;
|
||||||
use crate::{
|
use crate::{from_reflect, impls, ReflectDerive, REFLECT_ATTRIBUTE_NAME};
|
||||||
from_reflect, impls, ReflectDerive, REFLECT_ATTRIBUTE_NAME, REFLECT_VALUE_ATTRIBUTE_NAME,
|
|
||||||
};
|
|
||||||
use bevy_macro_utils::fq_std::FQOption;
|
use bevy_macro_utils::fq_std::FQOption;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::{Ident, Span};
|
use proc_macro2::{Ident, Span};
|
||||||
@ -70,10 +68,10 @@ pub(crate) fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStre
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ReflectDerive::Value(meta) => (
|
ReflectDerive::Opaque(meta) => (
|
||||||
impls::impl_value(&meta),
|
impls::impl_opaque(&meta),
|
||||||
if meta.from_reflect().should_auto_derive() {
|
if meta.from_reflect().should_auto_derive() {
|
||||||
Some(from_reflect::impl_value(&meta))
|
Some(from_reflect::impl_opaque(&meta))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
@ -114,10 +112,10 @@ fn generate_remote_wrapper(input: &DeriveInput, remote_ty: &TypePath) -> proc_ma
|
|||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
let ty_generics = &input.generics;
|
let ty_generics = &input.generics;
|
||||||
let where_clause = &input.generics.where_clause;
|
let where_clause = &input.generics.where_clause;
|
||||||
let attrs = input.attrs.iter().filter(|attr| {
|
let attrs = input
|
||||||
!attr.path().is_ident(REFLECT_ATTRIBUTE_NAME)
|
.attrs
|
||||||
&& !attr.path().is_ident(REFLECT_VALUE_ATTRIBUTE_NAME)
|
.iter()
|
||||||
});
|
.filter(|attr| !attr.path().is_ident(REFLECT_ATTRIBUTE_NAME));
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#(#attrs)*
|
#(#attrs)*
|
||||||
@ -407,7 +405,7 @@ fn generate_remote_definition_assertions(derive_data: &ReflectDerive) -> proc_ma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReflectDerive::Value(_) => {
|
ReflectDerive::Opaque(_) => {
|
||||||
// No assertions needed since there are no fields to check
|
// No assertions needed since there are no fields to check
|
||||||
proc_macro2::TokenStream::new()
|
proc_macro2::TokenStream::new()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
|
||||||
use glam::*;
|
use glam::*;
|
||||||
|
|
||||||
impl_reflect!(
|
impl_reflect!(
|
||||||
@ -343,8 +343,8 @@ impl_reflect!(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_value!(::glam::BVec3A(Debug, Default, Deserialize, Serialize));
|
impl_reflect_opaque!(::glam::BVec3A(Debug, Default, Deserialize, Serialize));
|
||||||
impl_reflect_value!(::glam::BVec4A(Debug, Default, Deserialize, Serialize));
|
impl_reflect_opaque!(::glam::BVec4A(Debug, Default, Deserialize, Serialize));
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
self as bevy_reflect, impl_reflect_value, prelude::ReflectDefault, ReflectDeserialize,
|
self as bevy_reflect, impl_reflect_opaque, prelude::ReflectDefault, ReflectDeserialize,
|
||||||
ReflectSerialize,
|
ReflectSerialize,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl_reflect_value!(::petgraph::graph::NodeIndex(
|
impl_reflect_opaque!(::petgraph::graph::NodeIndex(
|
||||||
Default,
|
Default,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::petgraph::graph::DiGraph<
|
impl_reflect_opaque!(::petgraph::graph::DiGraph<
|
||||||
N: ::std::clone::Clone,
|
N: ::std::clone::Clone,
|
||||||
E: ::std::clone::Clone,
|
E: ::std::clone::Clone,
|
||||||
Ix: ::petgraph::graph::IndexType
|
Ix: ::petgraph::graph::IndexType
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::{self as bevy_reflect};
|
use crate::{self as bevy_reflect};
|
||||||
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_reflect_derive::impl_reflect_value;
|
use bevy_reflect_derive::impl_reflect_opaque;
|
||||||
|
|
||||||
impl_reflect_value!(::smol_str::SmolStr(
|
impl_reflect_opaque!(::smol_str::SmolStr(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
|
@ -9,12 +9,12 @@ use crate::{
|
|||||||
self as bevy_reflect, impl_type_path, map_apply, map_partial_eq, map_try_apply,
|
self as bevy_reflect, impl_type_path, map_apply, map_partial_eq, map_try_apply,
|
||||||
reflect::impl_full_reflect, set_apply, set_partial_eq, set_try_apply, ApplyError, Array,
|
reflect::impl_full_reflect, set_apply, set_partial_eq, set_try_apply, ApplyError, Array,
|
||||||
ArrayInfo, ArrayIter, DynamicMap, DynamicSet, DynamicTypePath, FromReflect, FromType,
|
ArrayInfo, ArrayIter, DynamicMap, DynamicSet, DynamicTypePath, FromReflect, FromType,
|
||||||
GetTypeRegistration, List, ListInfo, ListIter, Map, MapInfo, MapIter, MaybeTyped,
|
GetTypeRegistration, List, ListInfo, ListIter, Map, MapInfo, MapIter, MaybeTyped, OpaqueInfo,
|
||||||
PartialReflect, Reflect, ReflectDeserialize, ReflectFromPtr, ReflectFromReflect, ReflectKind,
|
PartialReflect, Reflect, ReflectDeserialize, ReflectFromPtr, ReflectFromReflect, ReflectKind,
|
||||||
ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set, SetInfo, TypeInfo, TypePath,
|
ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set, SetInfo, TypeInfo, TypePath,
|
||||||
TypeRegistration, TypeRegistry, Typed, ValueInfo,
|
TypeRegistration, TypeRegistry, Typed,
|
||||||
};
|
};
|
||||||
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
@ -24,7 +24,7 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl_reflect_value!(bool(
|
impl_reflect_opaque!(bool(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -32,7 +32,7 @@ impl_reflect_value!(bool(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(char(
|
impl_reflect_opaque!(char(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -40,11 +40,11 @@ impl_reflect_value!(char(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(u8(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(u8(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(u16(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(u16(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(u32(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(u32(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(u64(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(u64(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(u128(
|
impl_reflect_opaque!(u128(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -52,7 +52,7 @@ impl_reflect_value!(u128(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(usize(
|
impl_reflect_opaque!(usize(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -60,11 +60,11 @@ impl_reflect_value!(usize(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(i8(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(i8(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(i16(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(i16(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(i32(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(i32(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(i64(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(i64(Debug, Hash, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(i128(
|
impl_reflect_opaque!(i128(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -72,7 +72,7 @@ impl_reflect_value!(i128(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(isize(
|
impl_reflect_opaque!(isize(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -80,10 +80,10 @@ impl_reflect_value!(isize(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(f32(Debug, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(f32(Debug, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_reflect_value!(f64(Debug, PartialEq, Serialize, Deserialize, Default));
|
impl_reflect_opaque!(f64(Debug, PartialEq, Serialize, Deserialize, Default));
|
||||||
impl_type_path!(str);
|
impl_type_path!(str);
|
||||||
impl_reflect_value!(::alloc::string::String(
|
impl_reflect_opaque!(::alloc::string::String(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -91,7 +91,7 @@ impl_reflect_value!(::alloc::string::String(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::std::path::PathBuf(
|
impl_reflect_opaque!(::std::path::PathBuf(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -99,16 +99,16 @@ impl_reflect_value!(::std::path::PathBuf(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::std::any::TypeId(Debug, Hash, PartialEq,));
|
impl_reflect_opaque!(::std::any::TypeId(Debug, Hash, PartialEq,));
|
||||||
impl_reflect_value!(::std::collections::BTreeSet<T: Ord + Eq + Clone + Send + Sync>());
|
impl_reflect_opaque!(::std::collections::BTreeSet<T: Ord + Eq + Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::Range<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::ops::Range<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::RangeInclusive<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::ops::RangeInclusive<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::RangeFrom<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::ops::RangeFrom<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::RangeTo<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::ops::RangeTo<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::RangeToInclusive<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::ops::RangeToInclusive<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::ops::RangeFull());
|
impl_reflect_opaque!(::core::ops::RangeFull());
|
||||||
impl_reflect_value!(::std::ops::Bound<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::std::ops::Bound<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::bevy_utils::Duration(
|
impl_reflect_opaque!(::bevy_utils::Duration(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -116,99 +116,99 @@ impl_reflect_value!(::bevy_utils::Duration(
|
|||||||
Deserialize,
|
Deserialize,
|
||||||
Default
|
Default
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::bevy_utils::Instant(Debug, Hash, PartialEq));
|
impl_reflect_opaque!(::bevy_utils::Instant(Debug, Hash, PartialEq));
|
||||||
impl_reflect_value!(::core::num::NonZeroI128(
|
impl_reflect_opaque!(::core::num::NonZeroI128(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroU128(
|
impl_reflect_opaque!(::core::num::NonZeroU128(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroIsize(
|
impl_reflect_opaque!(::core::num::NonZeroIsize(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroUsize(
|
impl_reflect_opaque!(::core::num::NonZeroUsize(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroI64(
|
impl_reflect_opaque!(::core::num::NonZeroI64(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroU64(
|
impl_reflect_opaque!(::core::num::NonZeroU64(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroU32(
|
impl_reflect_opaque!(::core::num::NonZeroU32(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroI32(
|
impl_reflect_opaque!(::core::num::NonZeroI32(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroI16(
|
impl_reflect_opaque!(::core::num::NonZeroI16(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroU16(
|
impl_reflect_opaque!(::core::num::NonZeroU16(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroU8(
|
impl_reflect_opaque!(::core::num::NonZeroU8(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::NonZeroI8(
|
impl_reflect_opaque!(::core::num::NonZeroI8(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
impl_reflect_value!(::core::num::Wrapping<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::num::Wrapping<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::core::num::Saturating<T: Clone + Send + Sync>());
|
impl_reflect_opaque!(::core::num::Saturating<T: Clone + Send + Sync>());
|
||||||
impl_reflect_value!(::std::sync::Arc<T: Send + Sync>);
|
impl_reflect_opaque!(::std::sync::Arc<T: Send + Sync>);
|
||||||
|
|
||||||
// `Serialize` and `Deserialize` only for platforms supported by serde:
|
// `Serialize` and `Deserialize` only for platforms supported by serde:
|
||||||
// https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732
|
// https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732
|
||||||
#[cfg(any(unix, windows))]
|
#[cfg(any(unix, windows))]
|
||||||
impl_reflect_value!(::std::ffi::OsString(
|
impl_reflect_opaque!(::std::ffi::OsString(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -216,8 +216,8 @@ impl_reflect_value!(::std::ffi::OsString(
|
|||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
#[cfg(not(any(unix, windows)))]
|
#[cfg(not(any(unix, windows)))]
|
||||||
impl_reflect_value!(::std::ffi::OsString(Debug, Hash, PartialEq));
|
impl_reflect_opaque!(::std::ffi::OsString(Debug, Hash, PartialEq));
|
||||||
impl_reflect_value!(::alloc::collections::BinaryHeap<T: Clone>);
|
impl_reflect_opaque!(::alloc::collections::BinaryHeap<T: Clone>);
|
||||||
|
|
||||||
macro_rules! impl_reflect_for_atomic {
|
macro_rules! impl_reflect_for_atomic {
|
||||||
($ty:ty, $ordering:expr) => {
|
($ty:ty, $ordering:expr) => {
|
||||||
@ -250,8 +250,8 @@ macro_rules! impl_reflect_for_atomic {
|
|||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| {
|
CELL.get_or_set(|| {
|
||||||
let info = ValueInfo::new::<Self>();
|
let info = OpaqueInfo::new::<Self>();
|
||||||
TypeInfo::Value(info)
|
TypeInfo::Opaque(info)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,19 +308,19 @@ macro_rules! impl_reflect_for_atomic {
|
|||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_kind(&self) -> ReflectKind {
|
fn reflect_kind(&self) -> ReflectKind {
|
||||||
ReflectKind::Value
|
ReflectKind::Opaque
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_ref(&self) -> ReflectRef {
|
fn reflect_ref(&self) -> ReflectRef {
|
||||||
ReflectRef::Value(self)
|
ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_mut(&mut self) -> ReflectMut {
|
fn reflect_mut(&mut self) -> ReflectMut {
|
||||||
ReflectMut::Value(self)
|
ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||||
ReflectOwned::Value(self)
|
ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Debug::fmt(self, f)
|
fmt::Debug::fmt(self, f)
|
||||||
@ -1542,19 +1542,19 @@ impl PartialReflect for Cow<'static, str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_kind(&self) -> ReflectKind {
|
fn reflect_kind(&self) -> ReflectKind {
|
||||||
ReflectKind::Value
|
ReflectKind::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_ref(&self) -> ReflectRef {
|
fn reflect_ref(&self) -> ReflectRef {
|
||||||
ReflectRef::Value(self)
|
ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_mut(&mut self) -> ReflectMut {
|
fn reflect_mut(&mut self) -> ReflectMut {
|
||||||
ReflectMut::Value(self)
|
ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||||
ReflectOwned::Value(self)
|
ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
||||||
@ -1599,7 +1599,7 @@ impl_full_reflect!(for Cow<'static, str>);
|
|||||||
impl Typed for Cow<'static, str> {
|
impl Typed for Cow<'static, str> {
|
||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1844,15 +1844,15 @@ impl PartialReflect for &'static str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_ref(&self) -> ReflectRef {
|
fn reflect_ref(&self) -> ReflectRef {
|
||||||
ReflectRef::Value(self)
|
ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_mut(&mut self) -> ReflectMut {
|
fn reflect_mut(&mut self) -> ReflectMut {
|
||||||
ReflectMut::Value(self)
|
ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||||
ReflectOwned::Value(self)
|
ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
||||||
@ -1925,7 +1925,7 @@ impl Reflect for &'static str {
|
|||||||
impl Typed for &'static str {
|
impl Typed for &'static str {
|
||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1978,19 +1978,19 @@ impl PartialReflect for &'static Path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_kind(&self) -> ReflectKind {
|
fn reflect_kind(&self) -> ReflectKind {
|
||||||
ReflectKind::Value
|
ReflectKind::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_ref(&self) -> ReflectRef {
|
fn reflect_ref(&self) -> ReflectRef {
|
||||||
ReflectRef::Value(self)
|
ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_mut(&mut self) -> ReflectMut {
|
fn reflect_mut(&mut self) -> ReflectMut {
|
||||||
ReflectMut::Value(self)
|
ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||||
ReflectOwned::Value(self)
|
ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
||||||
@ -2059,7 +2059,7 @@ impl Reflect for &'static Path {
|
|||||||
impl Typed for &'static Path {
|
impl Typed for &'static Path {
|
||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2111,19 +2111,19 @@ impl PartialReflect for Cow<'static, Path> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_kind(&self) -> ReflectKind {
|
fn reflect_kind(&self) -> ReflectKind {
|
||||||
ReflectKind::Value
|
ReflectKind::Opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_ref(&self) -> ReflectRef {
|
fn reflect_ref(&self) -> ReflectRef {
|
||||||
ReflectRef::Value(self)
|
ReflectRef::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_mut(&mut self) -> ReflectMut {
|
fn reflect_mut(&mut self) -> ReflectMut {
|
||||||
ReflectMut::Value(self)
|
ReflectMut::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||||
ReflectOwned::Value(self)
|
ReflectOwned::Opaque(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
fn clone_value(&self) -> Box<dyn PartialReflect> {
|
||||||
@ -2196,7 +2196,7 @@ impl Reflect for Cow<'static, Path> {
|
|||||||
impl Typed for Cow<'static, Path> {
|
impl Typed for Cow<'static, Path> {
|
||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
|
|
||||||
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_reflect_derive::impl_reflect_value;
|
use bevy_reflect_derive::impl_reflect_opaque;
|
||||||
|
|
||||||
impl_reflect_value!(::uuid::Uuid(
|
impl_reflect_opaque!(::uuid::Uuid(
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Default,
|
Default,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::{self as bevy_reflect, impl_reflect_value, ReflectDeserialize, ReflectSerialize};
|
use crate::{self as bevy_reflect, impl_reflect_opaque, ReflectDeserialize, ReflectSerialize};
|
||||||
impl_reflect_value!(::wgpu_types::TextureFormat(
|
|
||||||
|
impl_reflect_opaque!(::wgpu_types::TextureFormat(
|
||||||
Debug,
|
Debug,
|
||||||
Hash,
|
Hash,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
|
@ -50,17 +50,21 @@ pub enum ReflectKind {
|
|||||||
/// [function-like]: Function
|
/// [function-like]: Function
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
Function,
|
Function,
|
||||||
/// A value-like type.
|
/// An opaque type.
|
||||||
///
|
///
|
||||||
/// This most often represents a primitive or opaque type,
|
/// This most often represents a type where it is either impossible, difficult,
|
||||||
/// where it is not possible, difficult, or not useful to reflect the type further.
|
/// or unuseful to reflect the type further.
|
||||||
///
|
///
|
||||||
/// For example, `u32` and `String` are examples of value-like types.
|
/// This includes types like `String` and `Instant`.
|
||||||
/// Additionally, any type that derives [`Reflect`] with the `#[reflect_value]` attribute
|
|
||||||
/// will be considered a value-like type.
|
|
||||||
///
|
///
|
||||||
/// [`Reflect`]: crate::Reflect
|
/// Despite not technically being opaque types,
|
||||||
Value,
|
/// primitives like `u32` `i32` are considered opaque for the purposes of reflection.
|
||||||
|
///
|
||||||
|
/// Additionally, any type that [derives `Reflect`] with the `#[reflect(opaque)]` attribute
|
||||||
|
/// will be considered an opaque type.
|
||||||
|
///
|
||||||
|
/// [derives `Reflect`]: bevy_reflect_derive::Reflect
|
||||||
|
Opaque,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ReflectKind {
|
impl std::fmt::Display for ReflectKind {
|
||||||
@ -76,7 +80,7 @@ impl std::fmt::Display for ReflectKind {
|
|||||||
ReflectKind::Enum => f.pad("enum"),
|
ReflectKind::Enum => f.pad("enum"),
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
ReflectKind::Function => f.pad("function"),
|
ReflectKind::Function => f.pad("function"),
|
||||||
ReflectKind::Value => f.pad("value"),
|
ReflectKind::Opaque => f.pad("opaque"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +101,7 @@ macro_rules! impl_reflect_kind_conversions {
|
|||||||
Self::Enum(_) => ReflectKind::Enum,
|
Self::Enum(_) => ReflectKind::Enum,
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
Self::Function(_) => ReflectKind::Function,
|
Self::Function(_) => ReflectKind::Function,
|
||||||
Self::Value(_) => ReflectKind::Value,
|
Self::Opaque(_) => ReflectKind::Opaque,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +119,7 @@ macro_rules! impl_reflect_kind_conversions {
|
|||||||
$name::Enum(_) => Self::Enum,
|
$name::Enum(_) => Self::Enum,
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
$name::Function(_) => Self::Function,
|
$name::Function(_) => Self::Function,
|
||||||
$name::Value(_) => Self::Value,
|
$name::Opaque(_) => Self::Opaque,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,14 +137,14 @@ pub struct ReflectKindMismatchError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_cast_method {
|
macro_rules! impl_cast_method {
|
||||||
($name:ident : Value => $retval:ty) => {
|
($name:ident : Opaque => $retval:ty) => {
|
||||||
#[doc = "Attempts a cast to a [`PartialReflect`] trait object."]
|
#[doc = "Attempts a cast to a [`PartialReflect`] trait object."]
|
||||||
#[doc = "\n\nReturns an error if `self` is not the [`Self::Value`] variant."]
|
#[doc = "\n\nReturns an error if `self` is not the [`Self::Opaque`] variant."]
|
||||||
pub fn $name(self) -> Result<$retval, ReflectKindMismatchError> {
|
pub fn $name(self) -> Result<$retval, ReflectKindMismatchError> {
|
||||||
match self {
|
match self {
|
||||||
Self::Value(value) => Ok(value),
|
Self::Opaque(value) => Ok(value),
|
||||||
_ => Err(ReflectKindMismatchError {
|
_ => Err(ReflectKindMismatchError {
|
||||||
expected: ReflectKind::Value,
|
expected: ReflectKind::Opaque,
|
||||||
received: self.kind(),
|
received: self.kind(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
@ -180,7 +184,7 @@ pub enum ReflectRef<'a> {
|
|||||||
Enum(&'a dyn Enum),
|
Enum(&'a dyn Enum),
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
Function(&'a dyn Function),
|
Function(&'a dyn Function),
|
||||||
Value(&'a dyn PartialReflect),
|
Opaque(&'a dyn PartialReflect),
|
||||||
}
|
}
|
||||||
impl_reflect_kind_conversions!(ReflectRef<'_>);
|
impl_reflect_kind_conversions!(ReflectRef<'_>);
|
||||||
|
|
||||||
@ -193,7 +197,7 @@ impl<'a> ReflectRef<'a> {
|
|||||||
impl_cast_method!(as_map: Map => &'a dyn Map);
|
impl_cast_method!(as_map: Map => &'a dyn Map);
|
||||||
impl_cast_method!(as_set: Set => &'a dyn Set);
|
impl_cast_method!(as_set: Set => &'a dyn Set);
|
||||||
impl_cast_method!(as_enum: Enum => &'a dyn Enum);
|
impl_cast_method!(as_enum: Enum => &'a dyn Enum);
|
||||||
impl_cast_method!(as_value: Value => &'a dyn PartialReflect);
|
impl_cast_method!(as_opaque: Opaque => &'a dyn PartialReflect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable enumeration of ["kinds"] of a reflected type.
|
/// A mutable enumeration of ["kinds"] of a reflected type.
|
||||||
@ -215,7 +219,7 @@ pub enum ReflectMut<'a> {
|
|||||||
Enum(&'a mut dyn Enum),
|
Enum(&'a mut dyn Enum),
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
Function(&'a mut dyn Function),
|
Function(&'a mut dyn Function),
|
||||||
Value(&'a mut dyn PartialReflect),
|
Opaque(&'a mut dyn PartialReflect),
|
||||||
}
|
}
|
||||||
impl_reflect_kind_conversions!(ReflectMut<'_>);
|
impl_reflect_kind_conversions!(ReflectMut<'_>);
|
||||||
|
|
||||||
@ -228,7 +232,7 @@ impl<'a> ReflectMut<'a> {
|
|||||||
impl_cast_method!(as_map: Map => &'a mut dyn Map);
|
impl_cast_method!(as_map: Map => &'a mut dyn Map);
|
||||||
impl_cast_method!(as_set: Set => &'a mut dyn Set);
|
impl_cast_method!(as_set: Set => &'a mut dyn Set);
|
||||||
impl_cast_method!(as_enum: Enum => &'a mut dyn Enum);
|
impl_cast_method!(as_enum: Enum => &'a mut dyn Enum);
|
||||||
impl_cast_method!(as_value: Value => &'a mut dyn PartialReflect);
|
impl_cast_method!(as_opaque: Opaque => &'a mut dyn PartialReflect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An owned enumeration of ["kinds"] of a reflected type.
|
/// An owned enumeration of ["kinds"] of a reflected type.
|
||||||
@ -250,7 +254,7 @@ pub enum ReflectOwned {
|
|||||||
Enum(Box<dyn Enum>),
|
Enum(Box<dyn Enum>),
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
Function(Box<dyn Function>),
|
Function(Box<dyn Function>),
|
||||||
Value(Box<dyn PartialReflect>),
|
Opaque(Box<dyn PartialReflect>),
|
||||||
}
|
}
|
||||||
impl_reflect_kind_conversions!(ReflectOwned);
|
impl_reflect_kind_conversions!(ReflectOwned);
|
||||||
|
|
||||||
@ -263,7 +267,7 @@ impl ReflectOwned {
|
|||||||
impl_cast_method!(into_map: Map => Box<dyn Map>);
|
impl_cast_method!(into_map: Map => Box<dyn Map>);
|
||||||
impl_cast_method!(into_set: Set => Box<dyn Set>);
|
impl_cast_method!(into_set: Set => Box<dyn Set>);
|
||||||
impl_cast_method!(into_enum: Enum => Box<dyn Enum>);
|
impl_cast_method!(into_enum: Enum => Box<dyn Enum>);
|
||||||
impl_cast_method!(into_value: Value => Box<dyn PartialReflect>);
|
impl_cast_method!(into_value: Opaque => Box<dyn PartialReflect>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -164,15 +164,17 @@
|
|||||||
//! we can just use the matching [`PartialReflect::as_partial_reflect`], [`PartialReflect::as_partial_reflect_mut`],
|
//! we can just use the matching [`PartialReflect::as_partial_reflect`], [`PartialReflect::as_partial_reflect_mut`],
|
||||||
//! or [`PartialReflect::into_partial_reflect`] methods.
|
//! or [`PartialReflect::into_partial_reflect`] methods.
|
||||||
//!
|
//!
|
||||||
//! ## Value Types
|
//! ## Opaque Types
|
||||||
//!
|
//!
|
||||||
//! Types that do not fall under one of the above subtraits,
|
//! Some types don't fall under a particular subtrait.
|
||||||
//! such as for primitives (e.g. `bool`, `usize`, etc.)
|
//!
|
||||||
//! and simple types (e.g. `String`, `Duration`),
|
//! These types hide their internal structure to reflection,
|
||||||
//! are referred to as _value_ types
|
//! either because it is not possible, difficult, or not useful to reflect its internals.
|
||||||
//! since methods like [`PartialReflect::reflect_ref`] return a [`ReflectRef::Value`] variant.
|
//! Such types are known as _opaque_ types.
|
||||||
//! While most other types contain their own `dyn Reflect` fields and data,
|
//!
|
||||||
//! these types generally cannot be broken down any further.
|
//! This includes truly opaque types like `String` or `Instant`,
|
||||||
|
//! but also includes all the primitive types (e.g. `bool`, `usize`, etc.)
|
||||||
|
//! since they can't be broken down any further.
|
||||||
//!
|
//!
|
||||||
//! # Dynamic Types
|
//! # Dynamic Types
|
||||||
//!
|
//!
|
||||||
@ -198,7 +200,7 @@
|
|||||||
//!
|
//!
|
||||||
//! They are most commonly used as "proxies" for other types,
|
//! They are most commonly used as "proxies" for other types,
|
||||||
//! where they contain the same data as— and therefore, represent— a concrete type.
|
//! where they contain the same data as— and therefore, represent— a concrete type.
|
||||||
//! The [`PartialReflect::clone_value`] method will return a dynamic type for all non-value types,
|
//! The [`PartialReflect::clone_value`] method will return a dynamic type for all non-opaque types,
|
||||||
//! allowing all types to essentially be "cloned".
|
//! allowing all types to essentially be "cloned".
|
||||||
//! And since dynamic types themselves implement [`PartialReflect`],
|
//! And since dynamic types themselves implement [`PartialReflect`],
|
||||||
//! we may pass them around just like most other reflected types.
|
//! we may pass them around just like most other reflected types.
|
||||||
@ -398,7 +400,7 @@
|
|||||||
//! The `TypedReflectSerializer` will simply output the serialized data.
|
//! The `TypedReflectSerializer` will simply output the serialized data.
|
||||||
//!
|
//!
|
||||||
//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
|
//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
|
||||||
//! where the underlying type will be a dynamic type representing some concrete type (except for value types).
|
//! where the underlying type will be a dynamic type representing some concrete type (except for opaque types).
|
||||||
//!
|
//!
|
||||||
//! Again, it's important to remember that dynamic types may need to be converted to their concrete counterparts
|
//! Again, it's important to remember that dynamic types may need to be converted to their concrete counterparts
|
||||||
//! in order to be used in certain cases.
|
//! in order to be used in certain cases.
|
||||||
@ -1792,7 +1794,7 @@ mod tests {
|
|||||||
// Cow<'static, str>
|
// Cow<'static, str>
|
||||||
type MyCowStr = Cow<'static, str>;
|
type MyCowStr = Cow<'static, str>;
|
||||||
|
|
||||||
let info = MyCowStr::type_info().as_value().unwrap();
|
let info = MyCowStr::type_info().as_opaque().unwrap();
|
||||||
|
|
||||||
assert!(info.is::<MyCowStr>());
|
assert!(info.is::<MyCowStr>());
|
||||||
assert_eq!(std::any::type_name::<MyCowStr>(), info.type_path());
|
assert_eq!(std::any::type_name::<MyCowStr>(), info.type_path());
|
||||||
@ -1837,7 +1839,7 @@ mod tests {
|
|||||||
// Value
|
// Value
|
||||||
type MyValue = String;
|
type MyValue = String;
|
||||||
|
|
||||||
let info = MyValue::type_info().as_value().unwrap();
|
let info = MyValue::type_info().as_opaque().unwrap();
|
||||||
|
|
||||||
assert!(info.is::<MyValue>());
|
assert!(info.is::<MyValue>());
|
||||||
assert_eq!(MyValue::type_path(), info.type_path());
|
assert_eq!(MyValue::type_path(), info.type_path());
|
||||||
@ -1956,7 +1958,7 @@ mod tests {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct SomePrimitive;
|
struct SomePrimitive;
|
||||||
impl_reflect_value!(
|
impl_reflect_opaque!(
|
||||||
/// Some primitive for which we have attributed custom documentation.
|
/// Some primitive for which we have attributed custom documentation.
|
||||||
(in bevy_reflect::tests) SomePrimitive
|
(in bevy_reflect::tests) SomePrimitive
|
||||||
);
|
);
|
||||||
@ -2172,27 +2174,6 @@ bevy_reflect::tests::Test {
|
|||||||
assert_eq!("Foo".to_string(), format!("{foo:?}"));
|
assert_eq!("Foo".to_string(), format!("{foo:?}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn multiple_reflect_value_lists() {
|
|
||||||
#[derive(Clone, Hash, PartialEq, Reflect)]
|
|
||||||
#[reflect_value(Debug, Hash)]
|
|
||||||
#[reflect_value(PartialEq)]
|
|
||||||
struct Foo(i32);
|
|
||||||
|
|
||||||
impl Debug for Foo {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "Foo")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let foo = Foo(123);
|
|
||||||
let foo: &dyn PartialReflect = &foo;
|
|
||||||
|
|
||||||
assert!(foo.reflect_hash().is_some());
|
|
||||||
assert_eq!(Some(true), foo.reflect_partial_eq(foo));
|
|
||||||
assert_eq!("Foo".to_string(), format!("{foo:?}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_debug_function() {
|
fn custom_debug_function() {
|
||||||
#[derive(Reflect)]
|
#[derive(Reflect)]
|
||||||
@ -2591,7 +2572,8 @@ bevy_reflect::tests::Test {
|
|||||||
// === Remote Wrapper === //
|
// === Remote Wrapper === //
|
||||||
#[reflect_remote(external_crate::TheirType)]
|
#[reflect_remote(external_crate::TheirType)]
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
#[reflect_value(Debug, Default)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Debug, Default)]
|
||||||
struct MyType {
|
struct MyType {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
array_debug, enum_debug, list_debug, map_debug, serde::Serializable, set_debug, struct_debug,
|
array_debug, enum_debug, list_debug, map_debug, serde::Serializable, set_debug, struct_debug,
|
||||||
tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, ReflectKind,
|
tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectKind,
|
||||||
ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
|
ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
|
||||||
ValueInfo,
|
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
@ -178,7 +177,7 @@ where
|
|||||||
/// a `List`, while `value` is a `Struct`).
|
/// a `List`, while `value` is a `Struct`).
|
||||||
/// - If `T` is any complex type and the corresponding fields or elements of
|
/// - If `T` is any complex type and the corresponding fields or elements of
|
||||||
/// `self` and `value` are not of the same type.
|
/// `self` and `value` are not of the same type.
|
||||||
/// - If `T` is a value type and `self` cannot be downcast to `T`
|
/// - If `T` is an opaque type and `self` cannot be downcast to `T`
|
||||||
fn apply(&mut self, value: &dyn PartialReflect) {
|
fn apply(&mut self, value: &dyn PartialReflect) {
|
||||||
PartialReflect::try_apply(self, value).unwrap();
|
PartialReflect::try_apply(self, value).unwrap();
|
||||||
}
|
}
|
||||||
@ -266,7 +265,7 @@ where
|
|||||||
ReflectRef::Enum(dyn_enum) => enum_debug(dyn_enum, f),
|
ReflectRef::Enum(dyn_enum) => enum_debug(dyn_enum, f),
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
ReflectRef::Function(dyn_function) => dyn_function.fmt(f),
|
ReflectRef::Function(dyn_function) => dyn_function.fmt(f),
|
||||||
ReflectRef::Value(_) => write!(f, "Reflect({})", self.reflect_type_path()),
|
ReflectRef::Opaque(_) => write!(f, "Reflect({})", self.reflect_type_path()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +496,7 @@ impl Debug for dyn Reflect {
|
|||||||
impl Typed for dyn Reflect {
|
impl Typed for dyn Reflect {
|
||||||
fn type_info() -> &'static TypeInfo {
|
fn type_info() -> &'static TypeInfo {
|
||||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ use std::fmt;
|
|||||||
///
|
///
|
||||||
/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.
|
/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.
|
||||||
///
|
///
|
||||||
/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data,
|
/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,
|
||||||
/// this `Box` will contain the expected type.
|
/// this `Box` will contain the expected type.
|
||||||
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
|
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
|
||||||
///
|
///
|
||||||
@ -69,7 +69,7 @@ use std::fmt;
|
|||||||
///
|
///
|
||||||
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
///
|
///
|
||||||
/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`,
|
/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,
|
||||||
/// // we know that its deserialized value will be a `DynamicStruct`,
|
/// // we know that its deserialized value will be a `DynamicStruct`,
|
||||||
/// // although it will represent `MyStruct`.
|
/// // although it will represent `MyStruct`.
|
||||||
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
|
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
|
||||||
@ -89,7 +89,7 @@ use std::fmt;
|
|||||||
/// [`ReflectSerializer`]: crate::serde::ReflectSerializer
|
/// [`ReflectSerializer`]: crate::serde::ReflectSerializer
|
||||||
/// [type path]: crate::TypePath::type_path
|
/// [type path]: crate::TypePath::type_path
|
||||||
/// [`Box<dyn Reflect>`]: crate::Reflect
|
/// [`Box<dyn Reflect>`]: crate::Reflect
|
||||||
/// [`ReflectKind::Value`]: crate::ReflectKind::Value
|
/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque
|
||||||
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
||||||
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
||||||
/// [`Box<DynamicList>`]: crate::DynamicList
|
/// [`Box<DynamicList>`]: crate::DynamicList
|
||||||
@ -165,7 +165,7 @@ impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> {
|
|||||||
///
|
///
|
||||||
/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.
|
/// This deserializer will return a [`Box<dyn Reflect>`] containing the deserialized data.
|
||||||
///
|
///
|
||||||
/// For value types (i.e. [`ReflectKind::Value`]) or types that register [`ReflectDeserialize`] type data,
|
/// For opaque types (i.e. [`ReflectKind::Opaque`]) or types that register [`ReflectDeserialize`] type data,
|
||||||
/// this `Box` will contain the expected type.
|
/// this `Box` will contain the expected type.
|
||||||
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
|
/// For example, deserializing an `i32` will return a `Box<i32>` (as a `Box<dyn Reflect>`).
|
||||||
///
|
///
|
||||||
@ -202,7 +202,7 @@ impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> {
|
|||||||
///
|
///
|
||||||
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
/// let output: Box<dyn PartialReflect> = reflect_deserializer.deserialize(&mut deserializer).unwrap();
|
||||||
///
|
///
|
||||||
/// // Since `MyStruct` is not a value type and does not register `ReflectDeserialize`,
|
/// // Since `MyStruct` is not an opaque type and does not register `ReflectDeserialize`,
|
||||||
/// // we know that its deserialized value will be a `DynamicStruct`,
|
/// // we know that its deserialized value will be a `DynamicStruct`,
|
||||||
/// // although it will represent `MyStruct`.
|
/// // although it will represent `MyStruct`.
|
||||||
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
|
/// assert!(output.as_partial_reflect().represents::<MyStruct>());
|
||||||
@ -221,7 +221,7 @@ impl<'a, 'de> DeserializeSeed<'de> for ReflectDeserializer<'a> {
|
|||||||
///
|
///
|
||||||
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
|
/// [`TypedReflectSerializer`]: crate::serde::TypedReflectSerializer
|
||||||
/// [`Box<dyn Reflect>`]: crate::Reflect
|
/// [`Box<dyn Reflect>`]: crate::Reflect
|
||||||
/// [`ReflectKind::Value`]: crate::ReflectKind::Value
|
/// [`ReflectKind::Opaque`]: crate::ReflectKind::Opaque
|
||||||
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
/// [`ReflectDeserialize`]: crate::ReflectDeserialize
|
||||||
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
/// [`Box<DynamicStruct>`]: crate::DynamicStruct
|
||||||
/// [`Box<DynamicList>`]: crate::DynamicList
|
/// [`Box<DynamicList>`]: crate::DynamicList
|
||||||
@ -345,7 +345,7 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> {
|
|||||||
dynamic_enum.set_represented_type(Some(self.registration.type_info()));
|
dynamic_enum.set_represented_type(Some(self.registration.type_info()));
|
||||||
Ok(Box::new(dynamic_enum))
|
Ok(Box::new(dynamic_enum))
|
||||||
}
|
}
|
||||||
TypeInfo::Value(_) => {
|
TypeInfo::Opaque(_) => {
|
||||||
// This case should already be handled
|
// This case should already be handled
|
||||||
Err(make_custom_error(format_args!(
|
Err(make_custom_error(format_args!(
|
||||||
"type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`",
|
"type `{type_path}` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`",
|
||||||
|
@ -196,7 +196,7 @@ impl<'a> Serialize for TypedReflectSerializer<'a> {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
ReflectRef::Function(_) => Err(make_custom_error("functions cannot be serialized")),
|
ReflectRef::Function(_) => Err(make_custom_error("functions cannot be serialized")),
|
||||||
ReflectRef::Value(_) => Err(serializable.err().unwrap()),
|
ReflectRef::Opaque(_) => Err(serializable.err().unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debug_stack")]
|
#[cfg(feature = "debug_stack")]
|
||||||
|
@ -32,7 +32,7 @@ use thiserror::Error;
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use std::any::Any;
|
/// # use std::any::Any;
|
||||||
/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, TypeInfo, TypePath, ValueInfo, ApplyError};
|
/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, TypeInfo, TypePath, OpaqueInfo, ApplyError};
|
||||||
/// # use bevy_reflect::utility::NonGenericTypeInfoCell;
|
/// # use bevy_reflect::utility::NonGenericTypeInfoCell;
|
||||||
/// use bevy_reflect::Typed;
|
/// use bevy_reflect::Typed;
|
||||||
///
|
///
|
||||||
@ -207,7 +207,7 @@ pub enum TypeInfo {
|
|||||||
Map(MapInfo),
|
Map(MapInfo),
|
||||||
Set(SetInfo),
|
Set(SetInfo),
|
||||||
Enum(EnumInfo),
|
Enum(EnumInfo),
|
||||||
Value(ValueInfo),
|
Opaque(OpaqueInfo),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeInfo {
|
impl TypeInfo {
|
||||||
@ -224,7 +224,7 @@ impl TypeInfo {
|
|||||||
Self::Map(info) => info.ty(),
|
Self::Map(info) => info.ty(),
|
||||||
Self::Set(info) => info.ty(),
|
Self::Set(info) => info.ty(),
|
||||||
Self::Enum(info) => info.ty(),
|
Self::Enum(info) => info.ty(),
|
||||||
Self::Value(info) => info.ty(),
|
Self::Opaque(info) => info.ty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ impl TypeInfo {
|
|||||||
Self::Map(info) => info.docs(),
|
Self::Map(info) => info.docs(),
|
||||||
Self::Set(info) => info.docs(),
|
Self::Set(info) => info.docs(),
|
||||||
Self::Enum(info) => info.docs(),
|
Self::Enum(info) => info.docs(),
|
||||||
Self::Value(info) => info.docs(),
|
Self::Opaque(info) => info.docs(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ impl TypeInfo {
|
|||||||
Self::Map(_) => ReflectKind::Map,
|
Self::Map(_) => ReflectKind::Map,
|
||||||
Self::Set(_) => ReflectKind::Set,
|
Self::Set(_) => ReflectKind::Set,
|
||||||
Self::Enum(_) => ReflectKind::Enum,
|
Self::Enum(_) => ReflectKind::Enum,
|
||||||
Self::Value(_) => ReflectKind::Value,
|
Self::Opaque(_) => ReflectKind::Opaque,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@ impl TypeInfo {
|
|||||||
impl_cast_method!(as_array: Array => ArrayInfo);
|
impl_cast_method!(as_array: Array => ArrayInfo);
|
||||||
impl_cast_method!(as_map: Map => MapInfo);
|
impl_cast_method!(as_map: Map => MapInfo);
|
||||||
impl_cast_method!(as_enum: Enum => EnumInfo);
|
impl_cast_method!(as_enum: Enum => EnumInfo);
|
||||||
impl_cast_method!(as_value: Value => ValueInfo);
|
impl_cast_method!(as_opaque: Opaque => OpaqueInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The base representation of a Rust type.
|
/// The base representation of a Rust type.
|
||||||
@ -516,22 +516,22 @@ macro_rules! impl_type_methods {
|
|||||||
|
|
||||||
pub(crate) use impl_type_methods;
|
pub(crate) use impl_type_methods;
|
||||||
|
|
||||||
/// A container for compile-time info related to general value types, including primitives.
|
/// A container for compile-time info related to reflection-opaque types, including primitives.
|
||||||
///
|
///
|
||||||
/// This typically represents a type which cannot be broken down any further. This is often
|
/// This typically represents a type which cannot be broken down any further. This is often
|
||||||
/// due to technical reasons (or by definition), but it can also be a purposeful choice.
|
/// due to technical reasons (or by definition), but it can also be a purposeful choice.
|
||||||
///
|
///
|
||||||
/// For example, [`i32`] cannot be broken down any further, so it is represented by a [`ValueInfo`].
|
/// For example, [`i32`] cannot be broken down any further, so it is represented by an [`OpaqueInfo`].
|
||||||
/// And while [`String`] itself is a struct, its fields are private, so we don't really treat
|
/// And while [`String`] itself is a struct, its fields are private, so we don't really treat
|
||||||
/// it _as_ a struct. It therefore makes more sense to represent it as a [`ValueInfo`].
|
/// it _as_ a struct. It therefore makes more sense to represent it as an [`OpaqueInfo`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ValueInfo {
|
pub struct OpaqueInfo {
|
||||||
ty: Type,
|
ty: Type,
|
||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
docs: Option<&'static str>,
|
docs: Option<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueInfo {
|
impl OpaqueInfo {
|
||||||
pub fn new<T: Reflect + TypePath + ?Sized>() -> Self {
|
pub fn new<T: Reflect + TypePath + ?Sized>() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ty: Type::of::<T>(),
|
ty: Type::of::<T>(),
|
||||||
@ -540,7 +540,7 @@ impl ValueInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the docstring for this value.
|
/// Sets the docstring for this type.
|
||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
pub fn with_docs(self, doc: Option<&'static str>) -> Self {
|
pub fn with_docs(self, doc: Option<&'static str>) -> Self {
|
||||||
Self { docs: doc, ..self }
|
Self { docs: doc, ..self }
|
||||||
@ -548,7 +548,7 @@ impl ValueInfo {
|
|||||||
|
|
||||||
impl_type_methods!(ty);
|
impl_type_methods!(ty);
|
||||||
|
|
||||||
/// The docstring of this dynamic value, if any.
|
/// The docstring of this dynamic type, if any.
|
||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
pub fn docs(&self) -> Option<&'static str> {
|
pub fn docs(&self) -> Option<&'static str> {
|
||||||
self.docs
|
self.docs
|
||||||
|
@ -92,7 +92,8 @@ pub struct ComputedCameraValues {
|
|||||||
///
|
///
|
||||||
/// <https://en.wikipedia.org/wiki/Exposure_(photography)>
|
/// <https://en.wikipedia.org/wiki/Exposure_(photography)>
|
||||||
#[derive(Component, Clone, Copy, Reflect)]
|
#[derive(Component, Clone, Copy, Reflect)]
|
||||||
#[reflect_value(Component, Default)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Component, Default)]
|
||||||
pub struct Exposure {
|
pub struct Exposure {
|
||||||
/// <https://en.wikipedia.org/wiki/Exposure_value#Tabulated_exposure_values>
|
/// <https://en.wikipedia.org/wiki/Exposure_value#Tabulated_exposure_values>
|
||||||
pub ev100: f32,
|
pub ev100: f32,
|
||||||
@ -614,7 +615,8 @@ impl Default for CameraOutputMode {
|
|||||||
|
|
||||||
/// Configures the [`RenderGraph`](crate::render_graph::RenderGraph) name assigned to be run for a given [`Camera`] entity.
|
/// Configures the [`RenderGraph`](crate::render_graph::RenderGraph) name assigned to be run for a given [`Camera`] entity.
|
||||||
#[derive(Component, Debug, Deref, DerefMut, Reflect, Clone)]
|
#[derive(Component, Debug, Deref, DerefMut, Reflect, Clone)]
|
||||||
#[reflect_value(Component, Debug)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Component, Debug)]
|
||||||
pub struct CameraRenderGraph(InternedRenderSubGraph);
|
pub struct CameraRenderGraph(InternedRenderSubGraph);
|
||||||
|
|
||||||
impl CameraRenderGraph {
|
impl CameraRenderGraph {
|
||||||
@ -901,7 +903,8 @@ pub fn camera_system<T: CameraProjection + Component>(
|
|||||||
|
|
||||||
/// This component lets you control the [`TextureUsages`] field of the main texture generated for the camera
|
/// This component lets you control the [`TextureUsages`] field of the main texture generated for the camera
|
||||||
#[derive(Component, ExtractComponent, Clone, Copy, Reflect)]
|
#[derive(Component, ExtractComponent, Clone, Copy, Reflect)]
|
||||||
#[reflect_value(Component, Default)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Component, Default)]
|
||||||
pub struct CameraMainTextureUsages(pub TextureUsages);
|
pub struct CameraMainTextureUsages(pub TextureUsages);
|
||||||
impl Default for CameraMainTextureUsages {
|
impl Default for CameraMainTextureUsages {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -91,7 +91,8 @@ bitflags::bitflags! {
|
|||||||
/// details.
|
/// details.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Serialize, Deserialize, Hash, Clone, Copy, PartialEq, Eq, Debug, Reflect)]
|
#[derive(Serialize, Deserialize, Hash, Clone, Copy, PartialEq, Eq, Debug, Reflect)]
|
||||||
#[reflect_value(Serialize, Deserialize, Hash, PartialEq, Debug)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Serialize, Deserialize, Hash, PartialEq, Debug)]
|
||||||
pub struct RenderAssetUsages: u8 {
|
pub struct RenderAssetUsages: u8 {
|
||||||
const MAIN_WORLD = 1 << 0;
|
const MAIN_WORLD = 1 << 0;
|
||||||
const RENDER_WORLD = 1 << 1;
|
const RENDER_WORLD = 1 << 1;
|
||||||
|
@ -27,7 +27,8 @@ impl Plugin for StoragePlugin {
|
|||||||
|
|
||||||
/// A storage buffer that is prepared as a [`RenderAsset`] and uploaded to the GPU.
|
/// A storage buffer that is prepared as a [`RenderAsset`] and uploaded to the GPU.
|
||||||
#[derive(Asset, Reflect, Debug, Clone)]
|
#[derive(Asset, Reflect, Debug, Clone)]
|
||||||
#[reflect_value(Default)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Default, Debug)]
|
||||||
pub struct ShaderStorageBuffer {
|
pub struct ShaderStorageBuffer {
|
||||||
/// Optional data used to initialize the buffer.
|
/// Optional data used to initialize the buffer.
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
|
@ -167,7 +167,8 @@ impl ImageFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Asset, Reflect, Debug, Clone)]
|
#[derive(Asset, Reflect, Debug, Clone)]
|
||||||
#[reflect_value(Default)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(Default, Debug)]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
// TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
|
// TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
|
||||||
|
@ -104,7 +104,7 @@ fn setup(type_registry: Res<AppTypeRegistry>) {
|
|||||||
// Deserializing returns a `Box<dyn PartialReflect>` value.
|
// Deserializing returns a `Box<dyn PartialReflect>` value.
|
||||||
// Generally, deserializing a value will return the "dynamic" variant of a type.
|
// Generally, deserializing a value will return the "dynamic" variant of a type.
|
||||||
// For example, deserializing a struct will return the DynamicStruct type.
|
// For example, deserializing a struct will return the DynamicStruct type.
|
||||||
// "Value types" will be deserialized as themselves.
|
// "Opaque types" will be deserialized as themselves.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
reflect_value.reflect_type_path(),
|
reflect_value.reflect_type_path(),
|
||||||
DynamicStruct::type_path(),
|
DynamicStruct::type_path(),
|
||||||
|
@ -53,12 +53,12 @@ pub struct E {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// By default, deriving with Reflect assumes the type is either a "struct" or an "enum".
|
/// By default, deriving with Reflect assumes the type is either a "struct" or an "enum".
|
||||||
/// You can tell reflect to treat your type instead as a "value type" by using the `reflect_value`
|
/// You can tell reflect to treat your type instead as an "opaque type" by using the `#[reflect(opaque)]`.
|
||||||
/// attribute in place of `reflect`. It is generally a good idea to implement (and reflect)
|
/// It is generally a good idea to implement (and reflect) the `PartialEq`, `Serialize`, and `Deserialize`
|
||||||
/// the `PartialEq`, `Serialize`, and `Deserialize` traits on `reflect_value` types to ensure
|
/// traits on opaque types to ensure that these values behave as expected when nested in other reflected types.
|
||||||
/// that these values behave as expected when nested underneath Reflect-ed structs.
|
|
||||||
#[derive(Reflect, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Reflect, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[reflect_value(PartialEq, Serialize, Deserialize)]
|
#[reflect(opaque)]
|
||||||
|
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum F {
|
enum F {
|
||||||
X,
|
X,
|
||||||
@ -118,10 +118,10 @@ fn setup() {
|
|||||||
// This variant only exists if the `reflect_functions` feature is enabled.
|
// This variant only exists if the `reflect_functions` feature is enabled.
|
||||||
#[cfg(feature = "reflect_functions")]
|
#[cfg(feature = "reflect_functions")]
|
||||||
ReflectRef::Function(_) => {}
|
ReflectRef::Function(_) => {}
|
||||||
// `Value` types do not implement any of the other traits above. They are simply a Reflect
|
// `Opaque` types do not implement any of the other traits above. They are simply a Reflect
|
||||||
// implementation. Value is implemented for core types like i32, usize, f32, and
|
// implementation. Opaque is implemented for opaque types like String and Instant,
|
||||||
// String.
|
// but also include primitive types like i32, usize, and f32 (despite not technically being opaque).
|
||||||
ReflectRef::Value(_) => {}
|
ReflectRef::Opaque(_) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dynamic_list = DynamicList::default();
|
let mut dynamic_list = DynamicList::default();
|
||||||
|
Loading…
Reference in New Issue
Block a user