Add no_std support to bevy_reflect (#16256)

# Objective

- Contributes to #15460

## Solution

- Added `std` feature (enabled by default)

## Testing

- CI
- `cargo check -p bevy_reflect --no-default-features --target
"x86_64-unknown-none"`
- UEFI demo application runs with this branch of `bevy_reflect`,
allowing `derive(Reflect)`

## Notes

- The [`spin`](https://crates.io/crates/spin) crate has been included to
provide `RwLock` and `Once` (as an alternative to `OnceLock`) when the
`std` feature is not enabled. Another alternative may be more desirable,
please provide feedback if you have a strong opinion here!
- Certain items (`Box`, `String`, `ToString`) provided by `alloc` have
been added to `__macro_exports` as a way to avoid `alloc` vs `std`
namespacing. I'm personally quite annoyed that we can't rely on `alloc`
as a crate name in `std` environments within macros. I'd love an
alternative to my approach here, but I suspect it's the least-bad
option.
- I would've liked to have an `alloc` feature (for allocation-free
`bevy_reflect`), unfortunately, `erased_serde` unconditionally requires
access to `Box`. Maybe one day we could design around this, but for now
it just means `bevy_reflect` requires `alloc`.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Zachary Harrold 2024-12-06 08:15:21 +11:00 committed by GitHub
parent 09b0b5df91
commit bf765e61b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
68 changed files with 364 additions and 143 deletions

View file

@ -10,14 +10,24 @@ keywords = ["bevy"]
rust-version = "1.81.0" rust-version = "1.81.0"
[features] [features]
default = ["smallvec", "debug", "alloc"] default = ["std", "smallvec", "debug"]
std = [
"bevy_utils/std",
"erased-serde/std",
"downcast-rs/std",
"serde/std",
"spin/std",
"glam?/std",
"smol_str?/std",
"uuid?/std",
]
# When enabled, provides Bevy-related reflection implementations # When enabled, provides Bevy-related reflection implementations
bevy = ["smallvec", "smol_str"] bevy = ["smallvec", "smol_str"]
glam = ["dep:glam"] glam = ["dep:glam"]
petgraph = ["dep:petgraph"] petgraph = ["dep:petgraph", "std"]
smallvec = ["dep:smallvec"] smallvec = ["dep:smallvec"]
uuid = ["dep:uuid"] uuid = ["dep:uuid"]
wgpu-types = ["dep:wgpu-types"] wgpu-types = ["dep:wgpu-types", "std"]
# Enables features useful for debugging reflection # Enables features useful for debugging reflection
debug = ["debug_stack"] debug = ["debug_stack"]
# When enabled, keeps track of the current serialization/deserialization context for better error messages # When enabled, keeps track of the current serialization/deserialization context for better error messages
@ -26,31 +36,45 @@ debug_stack = []
documentation = ["bevy_reflect_derive/documentation"] documentation = ["bevy_reflect_derive/documentation"]
# Enables function reflection # Enables function reflection
functions = ["bevy_reflect_derive/functions"] functions = ["bevy_reflect_derive/functions"]
alloc = []
[dependencies] [dependencies]
# bevy # bevy
bevy_reflect_derive = { path = "derive", version = "0.15.0-dev" } bevy_reflect_derive = { path = "derive", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev", default-features = false, features = [
"alloc",
] }
bevy_ptr = { path = "../bevy_ptr", version = "0.15.0-dev" } bevy_ptr = { path = "../bevy_ptr", version = "0.15.0-dev" }
# other # other
erased-serde = "0.4" erased-serde = { version = "0.4", default-features = false, features = [
disqualified = "1.0" "alloc",
downcast-rs = "1.2" ] }
disqualified = { version = "1.0", default-features = false }
downcast-rs = { version = "1.2", default-features = false }
derive_more = { version = "1", default-features = false, features = [ derive_more = { version = "1", default-features = false, features = [
"error", "error",
"from", "from",
"display", "display",
] } ] }
serde = "1" serde = { version = "1", default-features = false, features = ["alloc"] }
smallvec = { version = "1.11", optional = true } spin = { version = "0.9.8", default-features = false, features = [
"once",
"rwlock",
] }
assert_type_match = "0.1.1" assert_type_match = "0.1.1"
glam = { version = "0.29", features = ["serde"], optional = true } smallvec = { version = "1.11", default-features = false, optional = true }
glam = { version = "0.29", default-features = false, features = [
"serde",
], optional = true }
petgraph = { version = "0.6", features = ["serde-1"], optional = true } petgraph = { version = "0.6", features = ["serde-1"], optional = true }
smol_str = { version = "0.2.0", features = ["serde"], optional = true } smol_str = { version = "0.2.0", default-features = false, features = [
uuid = { version = "1.0", optional = true, features = ["v4", "serde"] } "serde",
], optional = true }
uuid = { version = "1.0", default-features = false, optional = true, features = [
"v4",
"serde",
] }
variadics_please = "1.0" variadics_please = "1.0"
wgpu-types = { version = "23", features = ["serde"], optional = true } wgpu-types = { version = "23", features = ["serde"], optional = true }

View file

@ -280,9 +280,11 @@ impl<'a> ReflectDerive<'a> {
match &input.data { match &input.data {
Data::Struct(data) => { Data::Struct(data) => {
let fields = Self::collect_struct_fields(&data.fields)?; let fields = Self::collect_struct_fields(&data.fields)?;
let serialization_data =
SerializationDataDef::new(&fields, &meta.bevy_reflect_path)?;
let reflect_struct = ReflectStruct { let reflect_struct = ReflectStruct {
meta, meta,
serialization_data: SerializationDataDef::new(&fields)?, serialization_data,
fields, fields,
}; };
@ -1034,6 +1036,7 @@ impl<'a> ReflectTypePath<'a> {
fn reduce_generics( fn reduce_generics(
generics: &Generics, generics: &Generics,
mut ty_generic_fn: impl FnMut(&TypeParam) -> StringExpr, mut ty_generic_fn: impl FnMut(&TypeParam) -> StringExpr,
bevy_reflect_path: &Path,
) -> StringExpr { ) -> StringExpr {
let mut params = generics.params.iter().filter_map(|param| match param { let mut params = generics.params.iter().filter_map(|param| match param {
GenericParam::Type(type_param) => Some(ty_generic_fn(type_param)), GenericParam::Type(type_param) => Some(ty_generic_fn(type_param)),
@ -1042,7 +1045,7 @@ impl<'a> ReflectTypePath<'a> {
let ty = &const_param.ty; let ty = &const_param.ty;
Some(StringExpr::Owned(quote! { Some(StringExpr::Owned(quote! {
<#ty as ::std::string::ToString>::to_string(&#ident) <#ty as #bevy_reflect_path::__macro_exports::alloc_utils::ToString>::to_string(&#ident)
})) }))
} }
GenericParam::Lifetime(_) => None, GenericParam::Lifetime(_) => None,
@ -1074,6 +1077,7 @@ impl<'a> ReflectTypePath<'a> {
<#ident as #bevy_reflect_path::TypePath>::type_path() <#ident as #bevy_reflect_path::TypePath>::type_path()
}) })
}, },
bevy_reflect_path,
); );
StringExpr::from_iter([ StringExpr::from_iter([
@ -1111,6 +1115,7 @@ impl<'a> ReflectTypePath<'a> {
<#ident as #bevy_reflect_path::TypePath>::short_type_path() <#ident as #bevy_reflect_path::TypePath>::short_type_path()
}) })
}, },
bevy_reflect_path,
); );
StringExpr::from_iter([ StringExpr::from_iter([

View file

@ -32,7 +32,7 @@ pub(crate) fn generate_generics(meta: &ReflectMeta) -> Option<TokenStream> {
Some(quote! { Some(quote! {
#bevy_reflect_path::GenericInfo::Type( #bevy_reflect_path::GenericInfo::Type(
#bevy_reflect_path::TypeParamInfo::new::<#ident>( #bevy_reflect_path::TypeParamInfo::new::<#ident>(
::std::borrow::Cow::Borrowed(#name), #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name),
) )
#with_default #with_default
) )
@ -53,7 +53,7 @@ pub(crate) fn generate_generics(meta: &ReflectMeta) -> Option<TokenStream> {
)] )]
#bevy_reflect_path::GenericInfo::Const( #bevy_reflect_path::GenericInfo::Const(
#bevy_reflect_path::ConstParamInfo::new::<#ty>( #bevy_reflect_path::ConstParamInfo::new::<#ty>(
::std::borrow::Cow::Borrowed(#name), #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name),
) )
#with_default #with_default
) )

View file

@ -1,4 +1,4 @@
use bevy_macro_utils::fq_std::{FQAny, FQBox, FQOption, FQResult}; use bevy_macro_utils::fq_std::{FQAny, FQOption, FQResult};
use quote::quote; use quote::quote;
@ -17,8 +17,8 @@ pub fn impl_full_reflect(
let any_impls = if meta.is_remote_wrapper() { let any_impls = if meta.is_remote_wrapper() {
quote! { quote! {
#[inline] #[inline]
fn into_any(self: #FQBox<Self>) -> #FQBox<dyn #FQAny> { fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #FQAny> {
#FQBox::new(self.0) #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(self.0)
} }
#[inline] #[inline]
@ -34,7 +34,7 @@ pub fn impl_full_reflect(
} else { } else {
quote! { quote! {
#[inline] #[inline]
fn into_any(self: #FQBox<Self>) -> #FQBox<dyn #FQAny> { fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #FQAny> {
self self
} }
@ -55,7 +55,7 @@ pub fn impl_full_reflect(
#any_impls #any_impls
#[inline] #[inline]
fn into_reflect(self: #FQBox<Self>) -> #FQBox<dyn #bevy_reflect_path::Reflect> { fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect> {
self self
} }
@ -72,8 +72,8 @@ pub fn impl_full_reflect(
#[inline] #[inline]
fn set( fn set(
&mut self, &mut self,
value: #FQBox<dyn #bevy_reflect_path::Reflect> value: #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>
) -> #FQResult<(), #FQBox<dyn #bevy_reflect_path::Reflect>> { ) -> #FQResult<(), #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>> {
*self = <dyn #bevy_reflect_path::Reflect>::take(value)?; *self = <dyn #bevy_reflect_path::Reflect>::take(value)?;
#FQResult::Ok(()) #FQResult::Ok(())
} }
@ -119,8 +119,8 @@ pub fn common_partial_reflect_methods(
quote! { quote! {
#[inline] #[inline]
fn try_into_reflect( fn try_into_reflect(
self: #FQBox<Self> self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>
) -> #FQResult<#FQBox<dyn #bevy_reflect_path::Reflect>, #FQBox<dyn #bevy_reflect_path::PartialReflect>> { ) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect>> {
#FQResult::Ok(self) #FQResult::Ok(self)
} }
@ -135,7 +135,7 @@ pub fn common_partial_reflect_methods(
} }
#[inline] #[inline]
fn into_partial_reflect(self: #FQBox<Self>) -> #FQBox<dyn #bevy_reflect_path::PartialReflect> { fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
self self
} }

View file

@ -3,7 +3,7 @@ use crate::{
enum_utility::{EnumVariantOutputData, TryApplyVariantBuilder, VariantBuilder}, enum_utility::{EnumVariantOutputData, TryApplyVariantBuilder, VariantBuilder},
impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed}, impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
}; };
use bevy_macro_utils::fq_std::{FQBox, FQOption, FQResult}; use bevy_macro_utils::fq_std::{FQOption, FQResult};
use proc_macro2::{Ident, Span}; use proc_macro2::{Ident, Span};
use quote::quote; use quote::quote;
use syn::{Fields, Path}; use syn::{Fields, Path};
@ -186,8 +186,8 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream
} }
#[inline] #[inline]
fn clone_value(&self) -> #FQBox<dyn #bevy_reflect_path::PartialReflect> { fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
#FQBox::new(#bevy_reflect_path::Enum::clone_dynamic(self)) #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::Enum::clone_dynamic(self))
} }
#[inline] #[inline]
@ -256,7 +256,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream
#bevy_reflect_path::ReflectMut::Enum(self) #bevy_reflect_path::ReflectMut::Enum(self)
} }
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned { fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
#bevy_reflect_path::ReflectOwned::Enum(self) #bevy_reflect_path::ReflectOwned::Enum(self)
} }

View file

@ -3,7 +3,7 @@ use crate::{
where_clause_options::WhereClauseOptions, where_clause_options::WhereClauseOptions,
ReflectMeta, ReflectMeta,
}; };
use bevy_macro_utils::fq_std::{FQBox, FQClone, FQOption, FQResult}; use bevy_macro_utils::fq_std::{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.
@ -77,8 +77,8 @@ pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
} }
#[inline] #[inline]
fn clone_value(&self) -> #FQBox<dyn #bevy_reflect_path::PartialReflect> { fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
#FQBox::new(#FQClone::clone(self)) #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#FQClone::clone(self))
} }
#[inline] #[inline]
@ -112,7 +112,7 @@ pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
} }
#[inline] #[inline]
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned { fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
#bevy_reflect_path::ReflectOwned::Opaque(self) #bevy_reflect_path::ReflectOwned::Opaque(self)
} }

View file

@ -3,7 +3,7 @@ use crate::{
struct_utility::FieldAccessors, struct_utility::FieldAccessors,
ReflectStruct, ReflectStruct,
}; };
use bevy_macro_utils::fq_std::{FQBox, FQDefault, FQOption, FQResult}; use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult};
use quote::{quote, ToTokens}; use quote::{quote, ToTokens};
/// Implements `Struct`, `GetTypeRegistration`, and `Reflect` for the given derive data. /// Implements `Struct`, `GetTypeRegistration`, and `Reflect` for the given derive data.
@ -134,8 +134,8 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
} }
#[inline] #[inline]
fn clone_value(&self) -> #FQBox<dyn #bevy_reflect_path::PartialReflect> { fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
#FQBox::new(#bevy_reflect_path::Struct::clone_dynamic(self)) #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::Struct::clone_dynamic(self))
} }
#[inline] #[inline]
@ -174,7 +174,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
#bevy_reflect_path::ReflectMut::Struct(self) #bevy_reflect_path::ReflectMut::Struct(self)
} }
#[inline] #[inline]
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned { fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
#bevy_reflect_path::ReflectOwned::Struct(self) #bevy_reflect_path::ReflectOwned::Struct(self)
} }

View file

@ -3,7 +3,7 @@ use crate::{
struct_utility::FieldAccessors, struct_utility::FieldAccessors,
ReflectStruct, ReflectStruct,
}; };
use bevy_macro_utils::fq_std::{FQBox, FQDefault, FQOption, FQResult}; use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult};
use quote::{quote, ToTokens}; use quote::{quote, ToTokens};
/// Implements `TupleStruct`, `GetTypeRegistration`, and `Reflect` for the given derive data. /// Implements `TupleStruct`, `GetTypeRegistration`, and `Reflect` for the given derive data.
@ -100,8 +100,8 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::
#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info()) #FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
} }
#[inline] #[inline]
fn clone_value(&self) -> #FQBox<dyn #bevy_reflect_path::PartialReflect> { fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
#FQBox::new(#bevy_reflect_path::TupleStruct::clone_dynamic(self)) #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::TupleStruct::clone_dynamic(self))
} }
#[inline] #[inline]
@ -139,7 +139,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::
#bevy_reflect_path::ReflectMut::TupleStruct(self) #bevy_reflect_path::ReflectMut::TupleStruct(self)
} }
#[inline] #[inline]
fn reflect_owned(self: #FQBox<Self>) -> #bevy_reflect_path::ReflectOwned { fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
#bevy_reflect_path::ReflectOwned::TupleStruct(self) #bevy_reflect_path::ReflectOwned::TupleStruct(self)
} }

View file

@ -106,27 +106,34 @@ pub(crate) fn impl_type_path(meta: &ReflectMeta) -> TokenStream {
quote! { quote! {
#primitive_assert #primitive_assert
impl #impl_generics #bevy_reflect_path::TypePath for #type_path #ty_generics #where_reflect_clause { // To ensure alloc is available, but also prevent its name from clashing, we place the implementation inside an anonymous constant
fn type_path() -> &'static str { const _: () = {
#long_type_path extern crate alloc;
}
fn short_type_path() -> &'static str { use alloc::string::ToString;
#short_type_path
}
fn type_ident() -> Option<&'static str> { impl #impl_generics #bevy_reflect_path::TypePath for #type_path #ty_generics #where_reflect_clause {
#type_ident fn type_path() -> &'static str {
} #long_type_path
}
fn crate_name() -> Option<&'static str> { fn short_type_path() -> &'static str {
#crate_name #short_type_path
} }
fn module_path() -> Option<&'static str> { fn type_ident() -> Option<&'static str> {
#module_path #type_ident
}
fn crate_name() -> Option<&'static str> {
#crate_name
}
fn module_path() -> Option<&'static str> {
#module_path
}
} }
} };
} }
} }

View file

@ -2,7 +2,7 @@ use crate::{
derive_data::StructField, derive_data::StructField,
field_attributes::{DefaultBehavior, ReflectIgnoreBehavior}, field_attributes::{DefaultBehavior, ReflectIgnoreBehavior},
}; };
use bevy_macro_utils::fq_std::{FQBox, FQDefault}; use bevy_macro_utils::fq_std::FQDefault;
use quote::quote; use quote::quote;
use std::collections::HashMap; use std::collections::HashMap;
use syn::{spanned::Spanned, Path}; use syn::{spanned::Spanned, Path};
@ -20,7 +20,10 @@ impl SerializationDataDef {
/// ///
/// Returns `Ok(Some(data))` if there are any fields needing to be skipped during serialization. /// Returns `Ok(Some(data))` if there are any fields needing to be skipped during serialization.
/// Otherwise, returns `Ok(None)`. /// Otherwise, returns `Ok(None)`.
pub fn new(fields: &[StructField<'_>]) -> Result<Option<Self>, syn::Error> { pub fn new(
fields: &[StructField<'_>],
bevy_reflect_path: &Path,
) -> Result<Option<Self>, syn::Error> {
let mut skipped = HashMap::default(); let mut skipped = HashMap::default();
for field in fields { for field in fields {
@ -33,7 +36,7 @@ impl SerializationDataDef {
"internal error: field is missing a reflection index", "internal error: field is missing a reflection index",
) )
})?, })?,
SkippedFieldDef::new(field)?, SkippedFieldDef::new(field, bevy_reflect_path)?,
); );
} }
_ => continue, _ => continue,
@ -75,15 +78,15 @@ pub(crate) struct SkippedFieldDef {
} }
impl SkippedFieldDef { impl SkippedFieldDef {
pub fn new(field: &StructField<'_>) -> Result<Self, syn::Error> { pub fn new(field: &StructField<'_>, bevy_reflect_path: &Path) -> Result<Self, syn::Error> {
let ty = &field.data.ty; let ty = &field.data.ty;
let default_fn = match &field.attrs.default { let default_fn = match &field.attrs.default {
DefaultBehavior::Func(func) => quote! { DefaultBehavior::Func(func) => quote! {
|| { #FQBox::new(#func()) } || { #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#func()) }
}, },
_ => quote! { _ => quote! {
|| { #FQBox::new(<#ty as #FQDefault>::default()) } || { #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(<#ty as #FQDefault>::default()) }
}, },
}; };

View file

@ -44,9 +44,11 @@ impl StringExpr {
/// ///
/// [already owned]: StringExpr::Owned /// [already owned]: StringExpr::Owned
pub fn into_owned(self) -> TokenStream { pub fn into_owned(self) -> TokenStream {
let bevy_reflect_path = crate::meta::get_bevy_reflect_path();
match self { match self {
Self::Const(tokens) | Self::Borrowed(tokens) => quote! { Self::Const(tokens) | Self::Borrowed(tokens) => quote! {
::std::string::ToString::to_string(#tokens) #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#tokens)
}, },
Self::Owned(owned) => owned, Self::Owned(owned) => owned,
} }

View file

@ -1,5 +1,5 @@
use bevy_macro_utils::{ use bevy_macro_utils::{
fq_std::{FQBox, FQClone, FQOption, FQResult}, fq_std::{FQClone, FQOption, FQResult},
BevyManifest, BevyManifest,
}; };
use proc_macro::TokenStream; use proc_macro::TokenStream;
@ -57,7 +57,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr
#trait_vis struct #reflect_trait_ident { #trait_vis struct #reflect_trait_ident {
get_func: fn(&dyn #bevy_reflect_path::Reflect) -> #FQOption<&dyn #trait_ident>, get_func: fn(&dyn #bevy_reflect_path::Reflect) -> #FQOption<&dyn #trait_ident>,
get_mut_func: fn(&mut dyn #bevy_reflect_path::Reflect) -> #FQOption<&mut dyn #trait_ident>, get_mut_func: fn(&mut dyn #bevy_reflect_path::Reflect) -> #FQOption<&mut dyn #trait_ident>,
get_boxed_func: fn(#FQBox<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#FQBox<dyn #trait_ident>, #FQBox<dyn #bevy_reflect_path::Reflect>>, get_boxed_func: fn(#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>>,
} }
impl #reflect_trait_ident { impl #reflect_trait_ident {
@ -72,7 +72,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr
} }
#[doc = #get_box_doc] #[doc = #get_box_doc]
pub fn get_boxed(&self, reflect_value: #FQBox<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#FQBox<dyn #trait_ident>, #FQBox<dyn #bevy_reflect_path::Reflect>> { pub fn get_boxed(&self, reflect_value: #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>> {
(self.get_boxed_func)(reflect_value) (self.get_boxed_func)(reflect_value)
} }
} }
@ -87,7 +87,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr
<dyn #bevy_reflect_path::Reflect>::downcast_mut::<T>(reflect_value).map(|value| value as &mut dyn #trait_ident) <dyn #bevy_reflect_path::Reflect>::downcast_mut::<T>(reflect_value).map(|value| value as &mut dyn #trait_ident)
}, },
get_boxed_func: |reflect_value| { get_boxed_func: |reflect_value| {
<dyn #bevy_reflect_path::Reflect>::downcast::<T>(reflect_value).map(|value| value as #FQBox<dyn #trait_ident>) <dyn #bevy_reflect_path::Reflect>::downcast::<T>(reflect_value).map(|value| value as #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>)
} }
} }
} }

View file

@ -4,6 +4,7 @@ use crate::{
Generics, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, Generics, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned,
ReflectRef, Type, TypeInfo, TypePath, ReflectRef, Type, TypeInfo, TypePath,
}; };
use alloc::{boxed::Box, vec::Vec};
use bevy_reflect_derive::impl_type_path; use bevy_reflect_derive::impl_type_path;
use core::{ use core::{
any::Any, any::Any,

View file

@ -1,4 +1,5 @@
use crate::Reflect; use crate::Reflect;
use alloc::boxed::Box;
use bevy_utils::TypeIdMap; use bevy_utils::TypeIdMap;
use core::{ use core::{
any::TypeId, any::TypeId,
@ -16,7 +17,7 @@ use core::{
/// ///
/// ``` /// ```
/// # use bevy_reflect::{Reflect, Typed, TypeInfo}; /// # use bevy_reflect::{Reflect, Typed, TypeInfo};
/// use std::ops::RangeInclusive; /// use core::ops::RangeInclusive;
/// #[derive(Reflect)] /// #[derive(Reflect)]
/// struct Slider { /// struct Slider {
/// #[reflect(@RangeInclusive::<f32>::new(0.0, 1.0))] /// #[reflect(@RangeInclusive::<f32>::new(0.0, 1.0))]
@ -152,7 +153,7 @@ macro_rules! impl_custom_attribute_methods {
} }
#[allow(rustdoc::redundant_explicit_links)] #[allow(rustdoc::redundant_explicit_links)]
/// Gets a custom attribute by its [`TypeId`](std::any::TypeId). /// Gets a custom attribute by its [`TypeId`](core::any::TypeId).
/// ///
/// This is the dynamic equivalent of [`get_attribute`](Self::get_attribute). /// This is the dynamic equivalent of [`get_attribute`](Self::get_attribute).
pub fn get_attribute_by_id(&$self, id: ::core::any::TypeId) -> Option<&dyn $crate::Reflect> { pub fn get_attribute_by_id(&$self, id: ::core::any::TypeId) -> Option<&dyn $crate::Reflect> {

View file

@ -6,6 +6,7 @@ use crate::{
Struct, Tuple, TypeInfo, VariantFieldIter, VariantType, Struct, Tuple, TypeInfo, VariantFieldIter, VariantType,
}; };
use alloc::{boxed::Box, string::String};
use core::fmt::Formatter; use core::fmt::Formatter;
use derive_more::derive::From; use derive_more::derive::From;

View file

@ -4,7 +4,7 @@ use crate::{
type_info::impl_type_methods, type_info::impl_type_methods,
DynamicEnum, Generics, PartialReflect, Type, TypePath, VariantInfo, VariantType, DynamicEnum, Generics, PartialReflect, Type, TypePath, VariantInfo, VariantType,
}; };
use alloc::sync::Arc; use alloc::{boxed::Box, format, string::String, sync::Arc};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::slice::Iter; use core::slice::Iter;

View file

@ -2,10 +2,10 @@ use crate::{
attributes::{impl_custom_attribute_methods, CustomAttributes}, attributes::{impl_custom_attribute_methods, CustomAttributes},
NamedField, UnnamedField, NamedField, UnnamedField,
}; };
use alloc::boxed::Box;
use alloc::sync::Arc;
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::slice::Iter; use core::slice::Iter;
use alloc::sync::Arc;
use derive_more::derive::{Display, Error}; use derive_more::derive::{Display, Error};
/// Describes the form of an enum variant. /// Describes the form of an enum variant.

View file

@ -1,4 +1,5 @@
use crate::{FromType, PartialReflect, Reflect}; use crate::{FromType, PartialReflect, Reflect};
use alloc::boxed::Box;
/// A trait that enables types to be dynamically constructed from reflected data. /// A trait that enables types to be dynamically constructed from reflected data.
/// ///

View file

@ -2,8 +2,12 @@ use crate::{
func::args::{ArgError, FromArg, Ownership}, func::args::{ArgError, FromArg, Ownership},
PartialReflect, Reflect, TypePath, PartialReflect, Reflect, TypePath,
}; };
use alloc::boxed::Box;
use core::ops::Deref; use core::ops::Deref;
#[cfg(not(feature = "std"))]
use alloc::{format, vec};
/// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`].
/// ///
/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicFunction`]: crate::func::DynamicFunction

View file

@ -4,6 +4,9 @@ use derive_more::derive::{Display, Error};
use crate::func::args::Ownership; use crate::func::args::Ownership;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// An error that occurs when converting an [argument]. /// An error that occurs when converting an [argument].
/// ///
/// [argument]: crate::func::args::Arg /// [argument]: crate::func::args::Arg

View file

@ -1,5 +1,8 @@
use crate::func::args::{Arg, ArgError}; use crate::func::args::{Arg, ArgError};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A trait for types that can be created from an [`Arg`]. /// A trait for types that can be created from an [`Arg`].
/// ///
/// This trait exists so that types can be automatically converted into an [`Arg`] /// This trait exists so that types can be automatically converted into an [`Arg`]

View file

@ -6,6 +6,9 @@ use crate::{
Type, TypePath, Type, TypePath,
}; };
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// Type information for an [`Arg`] used in a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// Type information for an [`Arg`] used in a [`DynamicFunction`] or [`DynamicFunctionMut`].
/// ///
/// [`Arg`]: crate::func::args::Arg /// [`Arg`]: crate::func::args::Arg

View file

@ -5,7 +5,10 @@ use crate::{
}, },
PartialReflect, Reflect, TypePath, PartialReflect, Reflect, TypePath,
}; };
use alloc::collections::VecDeque; use alloc::{boxed::Box, collections::VecDeque};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A list of arguments that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// A list of arguments that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`].
/// ///

View file

@ -1,5 +1,8 @@
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A trait for getting the ownership of a type. /// A trait for getting the ownership of a type.
/// ///
/// This trait exists so that [`TypedFunction`] can automatically generate /// This trait exists so that [`TypedFunction`] can automatically generate

View file

@ -9,10 +9,13 @@ use crate::{
ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned,
ReflectRef, TypeInfo, TypePath, ReflectRef, TypeInfo, TypePath,
}; };
use alloc::{borrow::Cow, sync::Arc}; use alloc::{borrow::Cow, boxed::Box, sync::Arc};
use bevy_reflect_derive::impl_type_path; use bevy_reflect_derive::impl_type_path;
use core::fmt::{Debug, Formatter}; use core::fmt::{Debug, Formatter};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A dynamic representation of a function. /// A dynamic representation of a function.
/// ///
/// This type can be used to represent any callable that satisfies [`Fn`] /// This type can be used to represent any callable that satisfies [`Fn`]
@ -79,7 +82,7 @@ impl<'env> DynamicFunction<'env> {
/// Set the name of the function. /// Set the name of the function.
/// ///
/// For [`DynamicFunctions`] created using [`IntoFunction`], /// For [`DynamicFunctions`] created using [`IntoFunction`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///
@ -134,7 +137,7 @@ impl<'env> DynamicFunction<'env> {
/// The [name] of the function. /// The [name] of the function.
/// ///
/// For [`DynamicFunctions`] created using [`IntoFunction`], /// For [`DynamicFunctions`] created using [`IntoFunction`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///

View file

@ -1,6 +1,9 @@
use alloc::borrow::Cow; use alloc::{borrow::Cow, boxed::Box};
use core::fmt::{Debug, Formatter}; use core::fmt::{Debug, Formatter};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use crate::func::{ use crate::func::{
args::ArgList, info::FunctionInfo, DynamicFunction, FunctionError, FunctionResult, args::ArgList, info::FunctionInfo, DynamicFunction, FunctionError, FunctionResult,
IntoFunctionMut, IntoFunctionMut,
@ -90,7 +93,7 @@ impl<'env> DynamicFunctionMut<'env> {
/// Set the name of the function. /// Set the name of the function.
/// ///
/// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///
@ -195,7 +198,7 @@ impl<'env> DynamicFunctionMut<'env> {
/// The [name] of the function. /// The [name] of the function.
/// ///
/// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///

View file

@ -2,6 +2,9 @@ use crate::func::{args::ArgError, Return};
use alloc::borrow::Cow; use alloc::borrow::Cow;
use derive_more::derive::{Display, Error, From}; use derive_more::derive::{Display, Error, From};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// An error that occurs when calling a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// An error that occurs when calling a [`DynamicFunction`] or [`DynamicFunctionMut`].
/// ///
/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicFunction`]: crate::func::DynamicFunction

View file

@ -5,6 +5,9 @@ use crate::{
use alloc::borrow::Cow; use alloc::borrow::Cow;
use core::fmt::Debug; use core::fmt::Debug;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A trait used to power [function-like] operations via [reflection]. /// A trait used to power [function-like] operations via [reflection].
/// ///
/// This trait allows types to be called like regular functions /// This trait allows types to be called like regular functions
@ -36,7 +39,7 @@ pub trait Function: PartialReflect + Debug {
/// The name of the function, if any. /// The name of the function, if any.
/// ///
/// For [`DynamicFunctions`] created using [`IntoFunction`], /// For [`DynamicFunctions`] created using [`IntoFunction`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///

View file

@ -1,4 +1,7 @@
use alloc::borrow::Cow; use alloc::{borrow::Cow, vec};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use variadics_please::all_tuples; use variadics_please::all_tuples;
@ -109,7 +112,7 @@ impl FunctionInfo {
/// The name of the function. /// The name of the function.
/// ///
/// For [`DynamicFunctions`] created using [`IntoFunction`] or [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], /// For [`DynamicFunctions`] created using [`IntoFunction`] or [`DynamicFunctionMuts`] created using [`IntoFunctionMut`],
/// the default name will always be the full path to the function as returned by [`std::any::type_name`], /// the default name will always be the full path to the function as returned by [`core::any::type_name`],
/// unless the function is a closure, anonymous function, or function pointer, /// unless the function is a closure, anonymous function, or function pointer,
/// in which case the name will be `None`. /// in which case the name will be `None`.
/// ///
@ -351,7 +354,7 @@ all_tuples!(impl_typed_function, 0, 15, Arg, arg);
/// | Anonymous function | `foo::bar::{{closure}}` | `None` | /// | Anonymous function | `foo::bar::{{closure}}` | `None` |
/// | Function pointer | `fn() -> String` | `None` | /// | Function pointer | `fn() -> String` | `None` |
/// ///
/// [`type_name`]: std::any::type_name /// [`type_name`]: core::any::type_name
fn create_info<F>() -> FunctionInfo { fn create_info<F>() -> FunctionInfo {
let name = core::any::type_name::<F>(); let name = core::any::type_name::<F>();

View file

@ -1,5 +1,8 @@
use crate::func::{DynamicFunction, ReflectFn, TypedFunction}; use crate::func::{DynamicFunction, ReflectFn, TypedFunction};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A trait for types that can be converted into a [`DynamicFunction`]. /// A trait for types that can be converted into a [`DynamicFunction`].
/// ///
/// This trait is automatically implemented for any type that implements /// This trait is automatically implemented for any type that implements

View file

@ -1,5 +1,8 @@
use crate::func::{DynamicFunctionMut, ReflectFnMut, TypedFunction}; use crate::func::{DynamicFunctionMut, ReflectFnMut, TypedFunction};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// A trait for types that can be converted into a [`DynamicFunctionMut`]. /// A trait for types that can be converted into a [`DynamicFunctionMut`].
/// ///
/// This trait is automatically implemented for any type that implements /// This trait is automatically implemented for any type that implements

View file

@ -1,3 +1,6 @@
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// Helper macro to implement the necessary traits for function reflection. /// Helper macro to implement the necessary traits for function reflection.
/// ///
/// This macro calls the following macros: /// This macro calls the following macros:

View file

@ -1,5 +1,8 @@
use variadics_please::all_tuples; use variadics_please::all_tuples;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use crate::{ use crate::{
func::{ func::{
args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn, args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn,

View file

@ -1,5 +1,8 @@
use variadics_please::all_tuples; use variadics_please::all_tuples;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use crate::{ use crate::{
func::{ func::{
args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn, args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn,

View file

@ -2,6 +2,9 @@ use alloc::{borrow::Cow, sync::Arc};
use core::fmt::Debug; use core::fmt::Debug;
use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use crate::func::{ use crate::func::{
@ -167,13 +170,13 @@ impl FunctionRegistry {
/// a + b /// a + b
/// })? /// })?
/// // Registering an existing function with its type name /// // Registering an existing function with its type name
/// .register_with_name(std::any::type_name_of_val(&mul), mul)? /// .register_with_name(core::any::type_name_of_val(&mul), mul)?
/// // Registering an existing function with a custom name /// // Registering an existing function with a custom name
/// .register_with_name("my_crate::mul", mul)?; /// .register_with_name("my_crate::mul", mul)?;
/// ///
/// // Be careful not to register anonymous functions with their type name. /// // Be careful not to register anonymous functions with their type name.
/// // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}` /// // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}`
/// registry.register_with_name(std::any::type_name_of_val(&div), div)?; /// registry.register_with_name(core::any::type_name_of_val(&div), div)?;
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
@ -195,7 +198,7 @@ impl FunctionRegistry {
/// [name]: DynamicFunction::name /// [name]: DynamicFunction::name
/// [`register`]: Self::register /// [`register`]: Self::register
/// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name
/// [type name]: std::any::type_name /// [type name]: core::any::type_name
pub fn register_with_name<F, Marker>( pub fn register_with_name<F, Marker>(
&mut self, &mut self,
name: impl Into<Cow<'static, str>>, name: impl Into<Cow<'static, str>>,

View file

@ -1,4 +1,8 @@
use crate::PartialReflect; use crate::PartialReflect;
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::{format, vec};
/// The return type of a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// The return type of a [`DynamicFunction`] or [`DynamicFunctionMut`].
/// ///

View file

@ -1,7 +1,6 @@
use crate::type_info::impl_type_methods; use crate::type_info::impl_type_methods;
use crate::{Reflect, Type, TypePath}; use crate::{Reflect, Type, TypePath};
use alloc::borrow::Cow; use alloc::{borrow::Cow, boxed::Box, sync::Arc};
use alloc::sync::Arc;
use core::ops::Deref; use core::ops::Deref;
use derive_more::derive::From; use derive_more::derive::From;

View file

@ -4,6 +4,9 @@ use assert_type_match::assert_type_match;
use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
use glam::*; use glam::*;
#[cfg(not(feature = "std"))]
use alloc::format;
/// Reflects the given foreign type as an enum and asserts that the variants/fields match up. /// Reflects the given foreign type as an enum and asserts that the variants/fields match up.
macro_rules! reflect_enum { macro_rules! reflect_enum {
($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => { ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => {

View file

@ -1,7 +1,10 @@
use alloc::boxed::Box;
use bevy_reflect_derive::impl_type_path; use bevy_reflect_derive::impl_type_path;
use core::any::Any;
use smallvec::{Array as SmallArray, SmallVec}; use smallvec::{Array as SmallArray, SmallVec};
use core::any::Any; #[cfg(not(feature = "std"))]
use alloc::{format, vec};
use crate::{ use crate::{
self as bevy_reflect, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType, self as bevy_reflect, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType,

View file

@ -13,13 +13,15 @@ use crate::{
ReflectFromReflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set, ReflectFromReflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set,
SetInfo, TypeInfo, TypeParamInfo, TypePath, TypeRegistration, TypeRegistry, Typed, SetInfo, TypeInfo, TypeParamInfo, TypePath, TypeRegistration, TypeRegistry, Typed,
}; };
use alloc::{borrow::Cow, collections::VecDeque}; use alloc::{borrow::Cow, borrow::ToOwned, boxed::Box, collections::VecDeque, format, vec::Vec};
use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
use core::{ use core::{
any::Any, any::Any,
fmt, fmt,
hash::{BuildHasher, Hash, Hasher}, hash::{BuildHasher, Hash, Hasher},
}; };
#[cfg(feature = "std")]
use std::path::Path; use std::path::Path;
impl_reflect_opaque!(bool( impl_reflect_opaque!(bool(
@ -89,6 +91,7 @@ impl_reflect_opaque!(::alloc::string::String(
Deserialize, Deserialize,
Default Default
)); ));
#[cfg(feature = "std")]
impl_reflect_opaque!(::std::path::PathBuf( impl_reflect_opaque!(::std::path::PathBuf(
Debug, Debug,
Hash, Hash,
@ -114,6 +117,7 @@ impl_reflect_opaque!(::bevy_utils::Duration(
Deserialize, Deserialize,
Default Default
)); ));
#[cfg(any(target_arch = "wasm32", feature = "std"))]
impl_reflect_opaque!(::bevy_utils::Instant(Debug, Hash, PartialEq)); impl_reflect_opaque!(::bevy_utils::Instant(Debug, Hash, PartialEq));
impl_reflect_opaque!(::core::num::NonZeroI128( impl_reflect_opaque!(::core::num::NonZeroI128(
Debug, Debug,
@ -205,7 +209,7 @@ impl_reflect_opaque!(::alloc::sync::Arc<T: Send + Sync + ?Sized>);
// `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(all(any(unix, windows), feature = "std"))]
impl_reflect_opaque!(::std::ffi::OsString( impl_reflect_opaque!(::std::ffi::OsString(
Debug, Debug,
Hash, Hash,
@ -213,7 +217,7 @@ impl_reflect_opaque!(::std::ffi::OsString(
Serialize, Serialize,
Deserialize Deserialize
)); ));
#[cfg(not(any(unix, windows)))] #[cfg(all(not(any(unix, windows)), feature = "std"))]
impl_reflect_opaque!(::std::ffi::OsString(Debug, Hash, PartialEq)); impl_reflect_opaque!(::std::ffi::OsString(Debug, Hash, PartialEq));
impl_reflect_opaque!(::alloc::collections::BinaryHeap<T: Clone>); impl_reflect_opaque!(::alloc::collections::BinaryHeap<T: Clone>);
@ -235,8 +239,14 @@ macro_rules! impl_reflect_for_atomic {
registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type()); registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type());
registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type()); registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type());
registration.insert::<ReflectDefault>(FromType::<Self>::from_type()); registration.insert::<ReflectDefault>(FromType::<Self>::from_type());
registration.insert::<ReflectSerialize>(FromType::<Self>::from_type());
registration.insert::<ReflectDeserialize>(FromType::<Self>::from_type()); // Serde only supports atomic types when the "std" feature is enabled
#[cfg(feature = "std")]
{
registration.insert::<ReflectSerialize>(FromType::<Self>::from_type());
registration.insert::<ReflectDeserialize>(FromType::<Self>::from_type());
}
registration registration
} }
} }
@ -820,10 +830,13 @@ macro_rules! impl_reflect_for_hashmap {
}; };
} }
#[cfg(feature = "std")]
impl_reflect_for_hashmap!(::std::collections::HashMap<K, V, S>); impl_reflect_for_hashmap!(::std::collections::HashMap<K, V, S>);
#[cfg(feature = "std")]
impl_type_path!(::std::collections::hash_map::RandomState); impl_type_path!(::std::collections::hash_map::RandomState);
#[cfg(feature = "std")]
impl_type_path!(::std::collections::HashMap<K, V, S>); impl_type_path!(::std::collections::HashMap<K, V, S>);
#[cfg(feature = "functions")] #[cfg(all(feature = "functions", feature = "std"))]
crate::func::macros::impl_function_traits!(::std::collections::HashMap<K, V, S>; crate::func::macros::impl_function_traits!(::std::collections::HashMap<K, V, S>;
< <
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
@ -1049,9 +1062,11 @@ macro_rules! impl_reflect_for_hashset {
impl_type_path!(::bevy_utils::NoOpHash); impl_type_path!(::bevy_utils::NoOpHash);
impl_type_path!(::bevy_utils::FixedState); impl_type_path!(::bevy_utils::FixedState);
#[cfg(feature = "std")]
impl_reflect_for_hashset!(::std::collections::HashSet<V,S>); impl_reflect_for_hashset!(::std::collections::HashSet<V,S>);
#[cfg(feature = "std")]
impl_type_path!(::std::collections::HashSet<V, S>); impl_type_path!(::std::collections::HashSet<V, S>);
#[cfg(feature = "functions")] #[cfg(all(feature = "functions", feature = "std"))]
crate::func::macros::impl_function_traits!(::std::collections::HashSet<V, S>; crate::func::macros::impl_function_traits!(::std::collections::HashSet<V, S>;
< <
V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration,
@ -1970,6 +1985,7 @@ impl FromReflect for &'static str {
#[cfg(feature = "functions")] #[cfg(feature = "functions")]
crate::func::macros::impl_function_traits!(&'static str); crate::func::macros::impl_function_traits!(&'static str);
#[cfg(feature = "std")]
impl PartialReflect for &'static Path { impl PartialReflect for &'static Path {
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
Some(<Self as Typed>::type_info()) Some(<Self as Typed>::type_info())
@ -2048,6 +2064,7 @@ impl PartialReflect for &'static Path {
} }
} }
#[cfg(feature = "std")]
impl Reflect for &'static Path { impl Reflect for &'static Path {
fn into_any(self: Box<Self>) -> Box<dyn Any> { fn into_any(self: Box<Self>) -> Box<dyn Any> {
self self
@ -2079,6 +2096,7 @@ impl Reflect for &'static Path {
} }
} }
#[cfg(feature = "std")]
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();
@ -2086,6 +2104,7 @@ impl Typed for &'static Path {
} }
} }
#[cfg(feature = "std")]
impl GetTypeRegistration for &'static Path { impl GetTypeRegistration for &'static Path {
fn get_type_registration() -> TypeRegistration { fn get_type_registration() -> TypeRegistration {
let mut registration = TypeRegistration::of::<Self>(); let mut registration = TypeRegistration::of::<Self>();
@ -2094,15 +2113,17 @@ impl GetTypeRegistration for &'static Path {
} }
} }
#[cfg(feature = "std")]
impl FromReflect for &'static Path { impl FromReflect for &'static Path {
fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> { fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
reflect.try_downcast_ref::<Self>().copied() reflect.try_downcast_ref::<Self>().copied()
} }
} }
#[cfg(feature = "functions")] #[cfg(all(feature = "functions", feature = "std"))]
crate::func::macros::impl_function_traits!(&'static Path); crate::func::macros::impl_function_traits!(&'static Path);
#[cfg(feature = "std")]
impl PartialReflect for Cow<'static, Path> { impl PartialReflect for Cow<'static, Path> {
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
Some(<Self as Typed>::type_info()) Some(<Self as Typed>::type_info())
@ -2185,6 +2206,7 @@ impl PartialReflect for Cow<'static, Path> {
} }
} }
#[cfg(feature = "std")]
impl Reflect for Cow<'static, Path> { impl Reflect for Cow<'static, Path> {
fn into_any(self: Box<Self>) -> Box<dyn Any> { fn into_any(self: Box<Self>) -> Box<dyn Any> {
self self
@ -2216,6 +2238,7 @@ impl Reflect for Cow<'static, Path> {
} }
} }
#[cfg(feature = "std")]
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();
@ -2223,15 +2246,18 @@ impl Typed for Cow<'static, Path> {
} }
} }
#[cfg(feature = "std")]
impl_type_path!(::std::path::Path); impl_type_path!(::std::path::Path);
impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>); impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>);
#[cfg(feature = "std")]
impl FromReflect for Cow<'static, Path> { impl FromReflect for Cow<'static, Path> {
fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> { fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
Some(reflect.try_downcast_ref::<Self>()?.clone()) Some(reflect.try_downcast_ref::<Self>()?.clone())
} }
} }
#[cfg(feature = "std")]
impl GetTypeRegistration for Cow<'static, Path> { impl GetTypeRegistration for Cow<'static, Path> {
fn get_type_registration() -> TypeRegistration { fn get_type_registration() -> TypeRegistration {
let mut registration = TypeRegistration::of::<Self>(); let mut registration = TypeRegistration::of::<Self>();
@ -2243,7 +2269,7 @@ impl GetTypeRegistration for Cow<'static, Path> {
} }
} }
#[cfg(feature = "functions")] #[cfg(all(feature = "functions", feature = "std"))]
crate::func::macros::impl_function_traits!(Cow<'static, Path>); crate::func::macros::impl_function_traits!(Cow<'static, Path>);
#[cfg(test)] #[cfg(test)]

View file

@ -1,3 +1,4 @@
use alloc::boxed::Box;
use derive_more::derive::{Display, Error}; use derive_more::derive::{Display, Error};
#[cfg(feature = "functions")] #[cfg(feature = "functions")]

View file

@ -553,6 +553,8 @@
//! [`ArgList`]: crate::func::ArgList //! [`ArgList`]: crate::func::ArgList
//! [derive `Reflect`]: derive@crate::Reflect //! [derive `Reflect`]: derive@crate::Reflect
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc; extern crate alloc;
mod array; mod array;
@ -651,6 +653,18 @@ pub mod __macro_exports {
DynamicTupleStruct, GetTypeRegistration, TypeRegistry, DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
}; };
/// Re-exports of items from the [`alloc`] crate.
///
/// This is required because in `std` environments (e.g., the `std` feature is enabled)
/// the `alloc` crate may not have been included, making its namespace unreliable.
pub mod alloc_utils {
pub use ::alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
string::ToString,
};
}
/// A wrapper trait around [`GetTypeRegistration`]. /// A wrapper trait around [`GetTypeRegistration`].
/// ///
/// This trait is used by the derive macro to recursively register all type dependencies. /// This trait is used by the derive macro to recursively register all type dependencies.

View file

@ -1,3 +1,4 @@
use alloc::{boxed::Box, vec::Vec};
use core::{ use core::{
any::Any, any::Any,
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},

View file

@ -9,6 +9,7 @@ use crate::{
PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo,
TypePath, TypePath,
}; };
use alloc::{boxed::Box, format, vec::Vec};
/// A trait used to power [map-like] operations via [reflection]. /// A trait used to power [map-like] operations via [reflection].
/// ///
@ -42,7 +43,7 @@ use crate::{
/// ``` /// ```
/// ///
/// [`HashMap`]: std::collections::HashMap /// [`HashMap`]: std::collections::HashMap
/// [`BTreeMap`]: std::collections::BTreeMap /// [`BTreeMap`]: alloc::collections::BTreeMap
/// [map-like]: https://doc.rust-lang.org/book/ch08-03-hash-maps.html /// [map-like]: https://doc.rust-lang.org/book/ch08-03-hash-maps.html
/// [reflection]: crate /// [reflection]: crate
pub trait Map: PartialReflect { pub trait Map: PartialReflect {

View file

@ -9,6 +9,7 @@ pub use parse::ParseError;
use parse::PathParser; use parse::PathParser;
use crate::{PartialReflect, Reflect}; use crate::{PartialReflect, Reflect};
use alloc::vec::Vec;
use core::fmt; use core::fmt;
use derive_more::derive::{Display, From}; use derive_more::derive::{Display, From};

View file

@ -3,6 +3,7 @@ use crate::{
tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectKind, tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectKind,
ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed, ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
}; };
use alloc::boxed::Box;
use core::{ use core::{
any::{Any, TypeId}, any::{Any, TypeId},
fmt::Debug, fmt::Debug,
@ -319,17 +320,17 @@ where
note = "consider annotating `{Self}` with `#[derive(Reflect)]`" note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
)] )]
pub trait Reflect: PartialReflect + DynamicTyped + Any { pub trait Reflect: PartialReflect + DynamicTyped + Any {
/// Returns the value as a [`Box<dyn Any>`][std::any::Any]. /// Returns the value as a [`Box<dyn Any>`][core::any::Any].
/// ///
/// For remote wrapper types, this will return the remote type instead. /// For remote wrapper types, this will return the remote type instead.
fn into_any(self: Box<Self>) -> Box<dyn Any>; fn into_any(self: Box<Self>) -> Box<dyn Any>;
/// Returns the value as a [`&dyn Any`][std::any::Any]. /// Returns the value as a [`&dyn Any`][core::any::Any].
/// ///
/// For remote wrapper types, this will return the remote type instead. /// For remote wrapper types, this will return the remote type instead.
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
/// Returns the value as a [`&mut dyn Any`][std::any::Any]. /// Returns the value as a [`&mut dyn Any`][core::any::Any].
/// ///
/// For remote wrapper types, this will return the remote type instead. /// For remote wrapper types, this will return the remote type instead.
fn as_any_mut(&mut self) -> &mut dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any;

View file

@ -41,7 +41,7 @@ use crate::Reflect;
/// ``` /// ```
/// ///
/// [reflectable]: Reflect /// [reflectable]: Reflect
/// [`transmute`]: std::mem::transmute /// [`transmute`]: core::mem::transmute
/// [very unsafe]: https://doc.rust-lang.org/1.71.0/nomicon/transmutes.html /// [very unsafe]: https://doc.rust-lang.org/1.71.0/nomicon/transmutes.html
/// [`FromReflect`]: crate::FromReflect /// [`FromReflect`]: crate::FromReflect
pub trait ReflectRemote: Reflect { pub trait ReflectRemote: Reflect {

View file

@ -2,6 +2,7 @@ use crate::{
serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer},
ArrayInfo, DynamicArray, TypeRegistry, ArrayInfo, DynamicArray, TypeRegistry,
}; };
use alloc::{string::ToString, vec::Vec};
use core::{fmt, fmt::Formatter}; use core::{fmt, fmt::Formatter};
use serde::de::{Error, SeqAccess, Visitor}; use serde::de::{Error, SeqAccess, Visitor};

View file

@ -1,5 +1,6 @@
use crate::serde::de::error_utils::make_custom_error; use crate::serde::de::error_utils::make_custom_error;
use crate::{FromType, PartialReflect, TypeRegistry}; use crate::{FromType, PartialReflect, TypeRegistry};
use alloc::boxed::Box;
use serde::Deserializer; use serde::Deserializer;
/// Trait used to provide finer control when deserializing a reflected type with one of /// Trait used to provide finer control when deserializing a reflected type with one of

View file

@ -12,6 +12,7 @@ use crate::{
}, },
PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry, PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry,
}; };
use alloc::boxed::Box;
use core::{fmt, fmt::Formatter}; use core::{fmt, fmt::Formatter};
use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor}; use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor};
@ -219,7 +220,7 @@ impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeser
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use std::any::TypeId; /// # use core::any::TypeId;
/// # use serde::de::DeserializeSeed; /// # use serde::de::DeserializeSeed;
/// # use bevy_reflect::prelude::*; /// # use bevy_reflect::prelude::*;
/// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; /// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer};

View file

@ -1,3 +1,7 @@
use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::{ use core::{
fmt, fmt,
fmt::{Debug, Display, Formatter}, fmt::{Debug, Display, Formatter},

View file

@ -1,4 +1,5 @@
use crate::{PartialReflect, TypeRegistration, TypeRegistry}; use crate::{PartialReflect, TypeRegistration, TypeRegistry};
use alloc::boxed::Box;
/// Allows overriding the default deserialization behavior of /// Allows overriding the default deserialization behavior of
/// [`ReflectDeserializer`] and [`TypedReflectDeserializer`] for specific /// [`ReflectDeserializer`] and [`TypedReflectDeserializer`] for specific

View file

@ -9,6 +9,7 @@ use crate::{
}, },
DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry, DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry,
}; };
use alloc::string::ToString;
use core::slice::Iter; use core::slice::Iter;
use serde::de::{Error, MapAccess, SeqAccess}; use serde::de::{Error, MapAccess, SeqAccess};

View file

@ -6,6 +6,7 @@ use crate::{
DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry, DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry,
UnnamedField, UnnamedField,
}; };
use alloc::string::ToString;
use serde::de::{Error, SeqAccess}; use serde::de::{Error, SeqAccess};
use super::ReflectDeserializerProcessor; use super::ReflectDeserializerProcessor;

View file

@ -1,3 +1,4 @@
use alloc::boxed::Box;
use core::ops::Deref; use core::ops::Deref;
/// A type-erased serializable value. /// A type-erased serializable value.

View file

@ -1,4 +1,5 @@
use crate::{FromType, Reflect, TypeRegistry}; use crate::{FromType, Reflect, TypeRegistry};
use alloc::boxed::Box;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
/// Trait used to provide finer control when serializing a reflected type with one of /// Trait used to provide finer control when serializing a reflected type with one of

View file

@ -1,4 +1,5 @@
use crate::Reflect; use crate::Reflect;
use alloc::boxed::Box;
use bevy_utils::{hashbrown::hash_map::Iter, HashMap}; use bevy_utils::{hashbrown::hash_map::Iter, HashMap};
/// Contains data relevant to the automatic reflect powered (de)serialization of a type. /// Contains data relevant to the automatic reflect powered (de)serialization of a type.
@ -26,7 +27,7 @@ impl SerializationData {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use std::any::TypeId; /// # use core::any::TypeId;
/// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData}; /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
/// #[derive(Reflect)] /// #[derive(Reflect)]
/// struct MyStruct { /// struct MyStruct {
@ -66,7 +67,7 @@ impl SerializationData {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use std::any::TypeId; /// # use core::any::TypeId;
/// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData}; /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
/// #[derive(Reflect)] /// #[derive(Reflect)]
/// struct MyStruct { /// struct MyStruct {

View file

@ -1,3 +1,4 @@
use alloc::{boxed::Box, format, vec::Vec};
use core::fmt::{Debug, Formatter}; use core::fmt::{Debug, Formatter};
use bevy_reflect_derive::impl_type_path; use bevy_reflect_derive::impl_type_path;
@ -42,7 +43,7 @@ use crate::{
/// ``` /// ```
/// ///
/// [`HashSet`]: std::collections::HashSet /// [`HashSet`]: std::collections::HashSet
/// [`BTreeSet`]: std::collections::BTreeSet /// [`BTreeSet`]: alloc::collections::BTreeSet
/// [set-like]: https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html /// [set-like]: https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html
/// [reflection]: crate /// [reflection]: crate
pub trait Set: PartialReflect { pub trait Set: PartialReflect {

View file

@ -1,4 +1,5 @@
use crate::{FromType, Reflect}; use crate::{FromType, Reflect};
use alloc::boxed::Box;
/// A struct used to provide the default value of a type. /// A struct used to provide the default value of a type.
/// ///

View file

@ -6,7 +6,7 @@ use crate::{
ApplyError, Generics, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut, ApplyError, Generics, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut,
ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
}; };
use alloc::{borrow::Cow, sync::Arc}; use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec};
use bevy_reflect_derive::impl_type_path; use bevy_reflect_derive::impl_type_path;
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::{ use core::{

View file

@ -8,6 +8,7 @@ use crate::{
ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry,
Typed, UnnamedField, Typed, UnnamedField,
}; };
use alloc::{boxed::Box, vec, vec::Vec};
use core::{ use core::{
any::Any, any::Any,
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
@ -376,7 +377,7 @@ impl FromIterator<Box<dyn PartialReflect>> for DynamicTuple {
impl IntoIterator for DynamicTuple { impl IntoIterator for DynamicTuple {
type Item = Box<dyn PartialReflect>; type Item = Box<dyn PartialReflect>;
type IntoIter = alloc::vec::IntoIter<Self::Item>; type IntoIter = vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.fields.into_iter() self.fields.into_iter()
@ -697,6 +698,7 @@ macro_rules! impl_type_path_tuple {
$(#[$meta])* $(#[$meta])*
impl <$param: TypePath> TypePath for ($param,) { impl <$param: TypePath> TypePath for ($param,) {
fn type_path() -> &'static str { fn type_path() -> &'static str {
use $crate::__macro_exports::alloc_utils::ToOwned;
static CELL: GenericTypePathCell = GenericTypePathCell::new(); static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| { CELL.get_or_insert::<Self, _>(|| {
"(".to_owned() + $param::type_path() + ",)" "(".to_owned() + $param::type_path() + ",)"
@ -704,6 +706,7 @@ macro_rules! impl_type_path_tuple {
} }
fn short_type_path() -> &'static str { fn short_type_path() -> &'static str {
use $crate::__macro_exports::alloc_utils::ToOwned;
static CELL: GenericTypePathCell = GenericTypePathCell::new(); static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| { CELL.get_or_insert::<Self, _>(|| {
"(".to_owned() + $param::short_type_path() + ",)" "(".to_owned() + $param::short_type_path() + ",)"
@ -716,6 +719,7 @@ macro_rules! impl_type_path_tuple {
$(#[$meta])* $(#[$meta])*
impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) { impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) {
fn type_path() -> &'static str { fn type_path() -> &'static str {
use $crate::__macro_exports::alloc_utils::ToOwned;
static CELL: GenericTypePathCell = GenericTypePathCell::new(); static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| { CELL.get_or_insert::<Self, _>(|| {
"(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")" "(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")"
@ -723,6 +727,7 @@ macro_rules! impl_type_path_tuple {
} }
fn short_type_path() -> &'static str { fn short_type_path() -> &'static str {
use $crate::__macro_exports::alloc_utils::ToOwned;
static CELL: GenericTypePathCell = GenericTypePathCell::new(); static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| { CELL.get_or_insert::<Self, _>(|| {
"(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")" "(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")"

View file

@ -8,7 +8,7 @@ use crate::{
ApplyError, DynamicTuple, Generics, PartialReflect, Reflect, ReflectKind, ReflectMut, ApplyError, DynamicTuple, Generics, PartialReflect, Reflect, ReflectKind, ReflectMut,
ReflectOwned, ReflectRef, Tuple, Type, TypeInfo, TypePath, UnnamedField, ReflectOwned, ReflectRef, Tuple, Type, TypeInfo, TypePath, UnnamedField,
}; };
use alloc::sync::Arc; use alloc::{boxed::Box, sync::Arc, vec::Vec};
use core::{ use core::{
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
slice::Iter, slice::Iter,

View file

@ -32,7 +32,7 @@ use derive_more::derive::{Display, Error};
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use std::any::Any; /// # use core::any::Any;
/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, TypeInfo, TypePath, OpaqueInfo, 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;
@ -498,7 +498,7 @@ macro_rules! impl_type_methods {
/// The [`TypeId`] of this type. /// The [`TypeId`] of this type.
/// ///
/// [`TypeId`]: std::any::TypeId /// [`TypeId`]: core::any::TypeId
pub fn type_id(&self) -> ::core::any::TypeId { pub fn type_id(&self) -> ::core::any::TypeId {
self.ty().id() self.ty().id()
} }
@ -528,7 +528,7 @@ macro_rules! impl_type_methods {
/// and does not verify they share the same [`TypePath`] /// and does not verify they share the same [`TypePath`]
/// (though it implies they do). /// (though it implies they do).
/// ///
/// [`TypeId`]: std::any::TypeId /// [`TypeId`]: core::any::TypeId
/// [`TypePath`]: crate::type_path::TypePath /// [`TypePath`]: crate::type_path::TypePath
pub fn is<T: ::core::any::Any>(&self) -> bool { pub fn is<T: ::core::any::Any>(&self) -> bool {
self.ty().is::<T>() self.ty().is::<T>()

View file

@ -4,6 +4,9 @@ use core::{
slice::Iter, slice::Iter,
}; };
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec};
/// Helper struct for managing a stack of [`TypeInfo`] instances. /// Helper struct for managing a stack of [`TypeInfo`] instances.
/// ///
/// This is useful for tracking the type hierarchy when serializing and deserializing types. /// This is useful for tracking the type hierarchy when serializing and deserializing types.

View file

@ -2,7 +2,7 @@ use core::fmt;
/// A static accessor to type paths and names. /// A static accessor to type paths and names.
/// ///
/// The engine uses this trait over [`std::any::type_name`] for stability and flexibility. /// The engine uses this trait over [`core::any::type_name`] for stability and flexibility.
/// ///
/// This trait is automatically implemented by the `#[derive(Reflect)]` macro /// This trait is automatically implemented by the `#[derive(Reflect)]` macro
/// and allows type path information to be processed without an instance of that type. /// and allows type path information to be processed without an instance of that type.
@ -16,7 +16,7 @@ use core::fmt;
/// Certain parts of the engine, e.g. [(de)serialization], rely on type paths as identifiers /// Certain parts of the engine, e.g. [(de)serialization], rely on type paths as identifiers
/// for matching dynamic values to concrete types. /// for matching dynamic values to concrete types.
/// ///
/// Using [`std::any::type_name`], a scene containing `my_crate::foo::MyComponent` would break, /// Using [`core::any::type_name`], a scene containing `my_crate::foo::MyComponent` would break,
/// failing to deserialize if the component was moved from the `foo` module to the `bar` module, /// failing to deserialize if the component was moved from the `foo` module to the `bar` module,
/// becoming `my_crate::bar::MyComponent`. /// becoming `my_crate::bar::MyComponent`.
/// This trait, through attributes when deriving itself or [`Reflect`], can ensure breaking changes are avoidable. /// This trait, through attributes when deriving itself or [`Reflect`], can ensure breaking changes are avoidable.

View file

@ -1,5 +1,6 @@
use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed}; use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed};
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::{boxed::Box, string::String};
use bevy_ptr::{Ptr, PtrMut}; use bevy_ptr::{Ptr, PtrMut};
use bevy_utils::{HashMap, HashSet, TypeIdMap}; use bevy_utils::{HashMap, HashSet, TypeIdMap};
use core::{ use core::{
@ -9,8 +10,13 @@ use core::{
}; };
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
use serde::Deserialize; use serde::Deserialize;
#[cfg(feature = "std")]
use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
#[cfg(not(feature = "std"))]
use spin::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
/// A registry of [reflected] types. /// A registry of [reflected] types.
/// ///
/// This struct is used as the central store for type information. /// This struct is used as the central store for type information.
@ -40,12 +46,12 @@ pub struct TypeRegistryArc {
impl Debug for TypeRegistryArc { impl Debug for TypeRegistryArc {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.internal let read_lock = self.internal.read();
.read()
.unwrap_or_else(PoisonError::into_inner) #[cfg(feature = "std")]
.type_path_to_id let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner);
.keys()
.fmt(f) read_lock.type_path_to_id.keys().fmt(f)
} }
} }
@ -131,7 +137,7 @@ impl TypeRegistry {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use std::any::TypeId; /// # use core::any::TypeId;
/// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault}; /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault};
/// #[derive(Reflect, Default)] /// #[derive(Reflect, Default)]
/// #[reflect(Default)] /// #[reflect(Default)]
@ -428,14 +434,22 @@ impl TypeRegistry {
impl TypeRegistryArc { impl TypeRegistryArc {
/// Takes a read lock on the underlying [`TypeRegistry`]. /// Takes a read lock on the underlying [`TypeRegistry`].
pub fn read(&self) -> RwLockReadGuard<'_, TypeRegistry> { pub fn read(&self) -> RwLockReadGuard<'_, TypeRegistry> {
self.internal.read().unwrap_or_else(PoisonError::into_inner) let read_lock = self.internal.read();
#[cfg(feature = "std")]
let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner);
read_lock
} }
/// Takes a write lock on the underlying [`TypeRegistry`]. /// Takes a write lock on the underlying [`TypeRegistry`].
pub fn write(&self) -> RwLockWriteGuard<'_, TypeRegistry> { pub fn write(&self) -> RwLockWriteGuard<'_, TypeRegistry> {
self.internal let write_lock = self.internal.write();
.write()
.unwrap_or_else(PoisonError::into_inner) #[cfg(feature = "std")]
let write_lock = write_lock.unwrap_or_else(PoisonError::into_inner);
write_lock
} }
} }
@ -746,7 +760,7 @@ impl<T: for<'a> Deserialize<'a> + Reflect> FromType<T> for ReflectDeserialize {
/// ``` /// ```
/// use bevy_reflect::{TypeRegistry, Reflect, ReflectFromPtr}; /// use bevy_reflect::{TypeRegistry, Reflect, ReflectFromPtr};
/// use bevy_ptr::Ptr; /// use bevy_ptr::Ptr;
/// use std::ptr::NonNull; /// use core::ptr::NonNull;
/// ///
/// #[derive(Reflect)] /// #[derive(Reflect)]
/// struct Reflected(String); /// struct Reflected(String);
@ -757,7 +771,7 @@ impl<T: for<'a> Deserialize<'a> + Reflect> FromType<T> for ReflectDeserialize {
/// let mut value = Reflected("Hello world!".to_string()); /// let mut value = Reflected("Hello world!".to_string());
/// let value = Ptr::from(&value); /// let value = Ptr::from(&value);
/// ///
/// let reflect_data = type_registry.get(std::any::TypeId::of::<Reflected>()).unwrap(); /// let reflect_data = type_registry.get(core::any::TypeId::of::<Reflected>()).unwrap();
/// let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap(); /// let reflect_from_ptr = reflect_data.data::<ReflectFromPtr>().unwrap();
/// // SAFE: `value` is of type `Reflected`, which the `ReflectFromPtr` was created for /// // SAFE: `value` is of type `Reflected`, which the `ReflectFromPtr` was created for
/// let value = unsafe { reflect_from_ptr.as_reflect(value) }; /// let value = unsafe { reflect_from_ptr.as_reflect(value) };

View file

@ -1,13 +1,19 @@
//! Helpers for working with Bevy reflection. //! Helpers for working with Bevy reflection.
use crate::TypeInfo; use crate::TypeInfo;
use alloc::boxed::Box;
use bevy_utils::{FixedState, NoOpHash, TypeIdMap}; use bevy_utils::{FixedState, NoOpHash, TypeIdMap};
use core::{ use core::{
any::{Any, TypeId}, any::{Any, TypeId},
hash::BuildHasher, hash::BuildHasher,
}; };
#[cfg(feature = "std")]
use std::sync::{OnceLock, PoisonError, RwLock}; use std::sync::{OnceLock, PoisonError, RwLock};
#[cfg(not(feature = "std"))]
use spin::{Once as OnceLock, RwLock};
/// A type that can be stored in a ([`Non`])[`GenericTypeCell`]. /// A type that can be stored in a ([`Non`])[`GenericTypeCell`].
/// ///
/// [`Non`]: NonGenericTypeCell /// [`Non`]: NonGenericTypeCell
@ -22,6 +28,7 @@ pub struct TypePathComponent;
mod sealed { mod sealed {
use super::{TypeInfo, TypePathComponent, TypedProperty}; use super::{TypeInfo, TypePathComponent, TypedProperty};
use alloc::string::String;
pub trait Sealed {} pub trait Sealed {}
@ -48,7 +55,7 @@ mod sealed {
/// ## Example /// ## Example
/// ///
/// ``` /// ```
/// # use std::any::Any; /// # use core::any::Any;
/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, Typed, TypeInfo, TypePath, ApplyError}; /// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, Typed, TypeInfo, TypePath, ApplyError};
/// use bevy_reflect::utility::NonGenericTypeInfoCell; /// use bevy_reflect::utility::NonGenericTypeInfoCell;
/// ///
@ -114,7 +121,11 @@ impl<T: TypedProperty> NonGenericTypeCell<T> {
where where
F: FnOnce() -> T::Stored, F: FnOnce() -> T::Stored,
{ {
self.0.get_or_init(f) #[cfg(feature = "std")]
return self.0.get_or_init(f);
#[cfg(not(feature = "std"))]
return self.0.call_once(f);
} }
} }
@ -137,7 +148,7 @@ impl<T: TypedProperty> Default for NonGenericTypeCell<T> {
/// Implementing [`TypeInfo`] with generics. /// Implementing [`TypeInfo`] with generics.
/// ///
/// ``` /// ```
/// # use std::any::Any; /// # use core::any::Any;
/// # use bevy_reflect::{DynamicTypePath, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TupleStructInfo, Typed, TypeInfo, TypePath, UnnamedField, ApplyError, Generics, TypeParamInfo}; /// # use bevy_reflect::{DynamicTypePath, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TupleStructInfo, Typed, TypeInfo, TypePath, UnnamedField, ApplyError, Generics, TypeParamInfo};
/// use bevy_reflect::utility::GenericTypeInfoCell; /// use bevy_reflect::utility::GenericTypeInfoCell;
/// ///
@ -186,7 +197,7 @@ impl<T: TypedProperty> Default for NonGenericTypeCell<T> {
/// Implementing [`TypePath`] with generics. /// Implementing [`TypePath`] with generics.
/// ///
/// ``` /// ```
/// # use std::any::Any; /// # use core::any::Any;
/// # use bevy_reflect::TypePath; /// # use bevy_reflect::TypePath;
/// use bevy_reflect::utility::GenericTypePathCell; /// use bevy_reflect::utility::GenericTypePathCell;
/// ///
@ -247,11 +258,12 @@ impl<T: TypedProperty> GenericTypeCell<T> {
/// ///
/// This method will then return the correct [`TypedProperty`] reference for the given type `T`. /// This method will then return the correct [`TypedProperty`] reference for the given type `T`.
fn get_by_type_id(&self, type_id: TypeId) -> Option<&T::Stored> { fn get_by_type_id(&self, type_id: TypeId) -> Option<&T::Stored> {
self.0 let read_lock = self.0.read();
.read()
.unwrap_or_else(PoisonError::into_inner) #[cfg(feature = "std")]
.get(&type_id) let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner);
.copied()
read_lock.get(&type_id).copied()
} }
/// Returns a reference to the [`TypedProperty`] stored in the cell. /// Returns a reference to the [`TypedProperty`] stored in the cell.
@ -269,9 +281,14 @@ impl<T: TypedProperty> GenericTypeCell<T> {
} }
fn insert_by_type_id(&self, type_id: TypeId, value: T::Stored) -> &T::Stored { fn insert_by_type_id(&self, type_id: TypeId, value: T::Stored) -> &T::Stored {
self.0 let write_lock = self.0.write();
.write()
.unwrap_or_else(PoisonError::into_inner) #[cfg(feature = "std")]
let write_lock = write_lock.unwrap_or_else(PoisonError::into_inner);
let mut write_lock = write_lock;
write_lock
.entry(type_id) .entry(type_id)
.insert({ .insert({
// We leak here in order to obtain a `&'static` reference. // We leak here in order to obtain a `&'static` reference.

View file

@ -62,6 +62,22 @@ impl Prepare for CompileCheckNoStdCommand {
"Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.", "Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.",
)); ));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_mikktspace --no-default-features --features libm --target {target}"
),
"Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_reflect --no-default-features --target {target}"
),
"Please fix compiler errors in output above for bevy_reflect no_std compatibility.",
));
commands.push(PreparedCommand::new::<Self>( commands.push(PreparedCommand::new::<Self>(
cmd!( cmd!(
sh, sh,