put automatic type registration behind feature gate
This commit is contained in:
parent
2ae4bb964d
commit
7c7bd79444
@ -130,6 +130,7 @@ default = [
|
||||
"hdr",
|
||||
"multi_threaded",
|
||||
"png",
|
||||
"reflect_auto_register",
|
||||
"smaa_luts",
|
||||
"sysinfo_plugin",
|
||||
"tonemapping_luts",
|
||||
@ -454,6 +455,9 @@ track_change_detection = ["bevy_internal/track_change_detection"]
|
||||
# Enable function reflection
|
||||
reflect_functions = ["bevy_internal/reflect_functions"]
|
||||
|
||||
# Enable automatic reflect registration
|
||||
reflect_auto_register = ["bevy_internal/reflect_auto_register"]
|
||||
|
||||
# Enable winit custom cursor support
|
||||
custom_cursor = ["bevy_internal/custom_cursor"]
|
||||
|
||||
|
||||
@ -18,6 +18,11 @@ reflect_functions = [
|
||||
"bevy_reflect/functions",
|
||||
"bevy_ecs/reflect_functions",
|
||||
]
|
||||
reflect_auto_register = [
|
||||
"bevy_reflect",
|
||||
"bevy_reflect/auto_register",
|
||||
"bevy_ecs/reflect_auto_register",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
|
||||
@ -91,7 +91,10 @@ impl Default for App {
|
||||
let mut app = App::empty();
|
||||
app.sub_apps.main.update_schedule = Some(Main.intern());
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
#[cfg(all(feature = "bevy_reflect", not(feature = "reflect_auto_register")))]
|
||||
app.init_resource::<AppTypeRegistry>();
|
||||
|
||||
#[cfg(feature = "reflect_auto_register")]
|
||||
app.insert_resource(AppTypeRegistry::new_with_derived_types());
|
||||
|
||||
#[cfg(feature = "reflect_functions")]
|
||||
|
||||
@ -18,6 +18,7 @@ bevy_debug_stepping = []
|
||||
serialize = ["dep:serde"]
|
||||
track_change_detection = []
|
||||
reflect_functions = ["bevy_reflect", "bevy_reflect/functions"]
|
||||
reflect_auto_register = ["bevy_reflect", "bevy_reflect/auto_register"]
|
||||
detailed_trace = []
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -53,6 +53,7 @@ impl AppTypeRegistry {
|
||||
/// Creates [`AppTypeRegistry`] and automatically registers all types deriving [`Reflect`].
|
||||
///
|
||||
/// See [`TypeRegistry::register_derived_types`] for more details.
|
||||
#[cfg(feature = "reflect_auto_register")]
|
||||
pub fn new_with_derived_types() -> Self {
|
||||
let app_registry = AppTypeRegistry::default();
|
||||
app_registry.write().register_derived_types();
|
||||
|
||||
@ -250,6 +250,12 @@ reflect_functions = [
|
||||
"bevy_app/reflect_functions",
|
||||
"bevy_ecs/reflect_functions",
|
||||
]
|
||||
# Enable automatic reflect registration
|
||||
reflect_auto_register = [
|
||||
"bevy_reflect/auto_register",
|
||||
"bevy_app/reflect_auto_register",
|
||||
"bevy_ecs/reflect_auto_register",
|
||||
]
|
||||
|
||||
# Enable winit custom cursor support
|
||||
custom_cursor = ["bevy_winit/custom_cursor"]
|
||||
|
||||
@ -26,6 +26,12 @@ debug_stack = []
|
||||
documentation = ["bevy_reflect_derive/documentation"]
|
||||
# Enables function reflection
|
||||
functions = ["bevy_reflect_derive/functions"]
|
||||
# Enables automatic reflect registration
|
||||
auto_register = [
|
||||
"bevy_reflect_derive/auto_register",
|
||||
"dep:inventory",
|
||||
"dep:wasm-init",
|
||||
]
|
||||
alloc = []
|
||||
|
||||
[dependencies]
|
||||
@ -55,9 +61,10 @@ wgpu-types = { version = "23", features = ["serde"], optional = true }
|
||||
|
||||
# deps for automatic type registration
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
inventory = "0.3"
|
||||
inventory = { version = "0.3", optional = true }
|
||||
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||
wasm-init = "0.2"
|
||||
wasm-init = { version = "0.2", optional = true }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
ron = "0.8.0"
|
||||
|
||||
@ -17,6 +17,8 @@ default = []
|
||||
documentation = []
|
||||
# Enables macro logic related to function reflection
|
||||
functions = []
|
||||
# Enables automatic reflect registration
|
||||
auto_register = []
|
||||
|
||||
[dependencies]
|
||||
bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.15.0-dev" }
|
||||
|
||||
@ -558,6 +558,8 @@ impl ContainerAttributes {
|
||||
}
|
||||
|
||||
/// Returns true if the `no_auto_register` attribute was found on this type.
|
||||
// This is not feature-gated because derive macro shouldn't break if auto_register feature is disabled.
|
||||
#[allow(dead_code)]
|
||||
pub fn no_auto_register(&self) -> bool {
|
||||
self.no_auto_register
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use bevy_macro_utils::fq_std::{FQAny, FQBox, FQOption, FQResult};
|
||||
|
||||
use quote::{quote, ToTokens};
|
||||
use quote::quote;
|
||||
|
||||
use crate::{derive_data::ReflectMeta, where_clause_options::WhereClauseOptions};
|
||||
|
||||
@ -157,7 +157,10 @@ pub fn common_partial_reflect_methods(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "auto_register")]
|
||||
pub fn reflect_auto_registration(meta: &ReflectMeta) -> Option<proc_macro2::TokenStream> {
|
||||
use quote::ToTokens;
|
||||
|
||||
if meta.attrs().no_auto_register() {
|
||||
return None;
|
||||
}
|
||||
@ -171,9 +174,9 @@ pub fn reflect_auto_registration(meta: &ReflectMeta) -> Option<proc_macro2::Toke
|
||||
};
|
||||
|
||||
Some(quote! {
|
||||
#bevy_reflect_path::__macro_exports::auto_register_function!{
|
||||
#bevy_reflect_path::__macro_exports::AutomaticReflectRegistrations::add(
|
||||
<#type_path as #bevy_reflect_path::__macro_exports::RegisterForReflection>::__register
|
||||
#bevy_reflect_path::__macro_exports::auto_register::auto_register_function!{
|
||||
#bevy_reflect_path::__macro_exports::auto_register::AutomaticReflectRegistrations::add(
|
||||
<#type_path as #bevy_reflect_path::__macro_exports::auto_register::RegisterForReflection>::__register
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
use crate::{
|
||||
derive_data::{EnumVariantFields, ReflectEnum, StructField},
|
||||
enum_utility::{EnumVariantOutputData, TryApplyVariantBuilder, VariantBuilder},
|
||||
impls::{
|
||||
common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed,
|
||||
reflect_auto_registration,
|
||||
},
|
||||
impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
|
||||
};
|
||||
use bevy_macro_utils::fq_std::{FQBox, FQOption, FQResult};
|
||||
use proc_macro2::{Ident, Span};
|
||||
@ -85,7 +82,10 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream
|
||||
let (impl_generics, ty_generics, where_clause) =
|
||||
reflect_enum.meta().type_path().generics().split_for_impl();
|
||||
|
||||
let auto_register = reflect_auto_registration(reflect_enum.meta());
|
||||
#[cfg(not(feature = "auto_register"))]
|
||||
let auto_register = None::<proc_macro2::TokenStream>;
|
||||
#[cfg(feature = "auto_register")]
|
||||
let auto_register = crate::impls::reflect_auto_registration(reflect_enum.meta());
|
||||
|
||||
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
||||
|
||||
|
||||
@ -9,9 +9,9 @@ mod tuple_structs;
|
||||
mod typed;
|
||||
|
||||
pub(crate) use assertions::impl_assertions;
|
||||
pub(crate) use common::{
|
||||
common_partial_reflect_methods, impl_full_reflect, reflect_auto_registration,
|
||||
};
|
||||
#[cfg(feature = "auto_register")]
|
||||
pub(crate) use common::reflect_auto_registration;
|
||||
pub(crate) use common::{common_partial_reflect_methods, impl_full_reflect};
|
||||
pub(crate) use enums::impl_enum;
|
||||
#[cfg(feature = "functions")]
|
||||
pub(crate) use func::impl_function_traits;
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
use crate::{
|
||||
impls::{
|
||||
common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed,
|
||||
reflect_auto_registration,
|
||||
},
|
||||
impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
|
||||
where_clause_options::WhereClauseOptions,
|
||||
ReflectMeta,
|
||||
};
|
||||
@ -58,7 +55,10 @@ pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
|
||||
#[cfg(feature = "functions")]
|
||||
let function_impls = crate::impls::impl_function_traits(meta, &where_clause_options);
|
||||
|
||||
let auto_register = reflect_auto_registration(meta);
|
||||
#[cfg(not(feature = "auto_register"))]
|
||||
let auto_register = None::<proc_macro2::TokenStream>;
|
||||
#[cfg(feature = "auto_register")]
|
||||
let auto_register = crate::impls::reflect_auto_registration(meta);
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
|
||||
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
use crate::{
|
||||
impls::{
|
||||
common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed,
|
||||
reflect_auto_registration,
|
||||
},
|
||||
impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
|
||||
struct_utility::FieldAccessors,
|
||||
ReflectStruct,
|
||||
};
|
||||
@ -65,7 +62,10 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
|
||||
.generics()
|
||||
.split_for_impl();
|
||||
|
||||
let auto_register = reflect_auto_registration(reflect_struct.meta());
|
||||
#[cfg(not(feature = "auto_register"))]
|
||||
let auto_register = None::<proc_macro2::TokenStream>;
|
||||
#[cfg(feature = "auto_register")]
|
||||
let auto_register = crate::impls::reflect_auto_registration(reflect_struct.meta());
|
||||
|
||||
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
||||
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
use crate::{
|
||||
impls::{
|
||||
common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed,
|
||||
reflect_auto_registration,
|
||||
},
|
||||
impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
|
||||
struct_utility::FieldAccessors,
|
||||
ReflectStruct,
|
||||
};
|
||||
@ -53,7 +50,10 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::
|
||||
.generics()
|
||||
.split_for_impl();
|
||||
|
||||
let auto_register = reflect_auto_registration(reflect_struct.meta());
|
||||
#[cfg(not(feature = "auto_register"))]
|
||||
let auto_register = None::<proc_macro2::TokenStream>;
|
||||
#[cfg(feature = "auto_register")]
|
||||
let auto_register = crate::impls::reflect_auto_registration(reflect_struct.meta());
|
||||
|
||||
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
||||
|
||||
|
||||
@ -687,76 +687,82 @@ pub mod __macro_exports {
|
||||
|
||||
impl RegisterForReflection for DynamicTuple {}
|
||||
|
||||
/// Stores registration functions of all reflect types that can be automatically registered.
|
||||
///
|
||||
/// Intended to be used as follows:
|
||||
/// ```rs
|
||||
/// // Adding a type
|
||||
/// auto_register_function!{
|
||||
/// AutomaticReflectRegistrations::add(<type_registration_function>)
|
||||
/// }
|
||||
///
|
||||
/// // Registering collected types
|
||||
/// let mut registry = TypeRegistry::default();
|
||||
/// AutomaticReflectRegistrations::register(&mut registry);
|
||||
/// ```
|
||||
pub struct AutomaticReflectRegistrations;
|
||||
/// Automatic reflect registration implementation
|
||||
#[cfg(feature = "auto_register")]
|
||||
pub mod auto_register {
|
||||
pub use super::*;
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
mod __automatic_type_registration_impl {
|
||||
use super::*;
|
||||
/// Stores registration functions of all reflect types that can be automatically registered.
|
||||
///
|
||||
/// Intended to be used as follows:
|
||||
/// ```rs
|
||||
/// // Adding a type
|
||||
/// auto_register_function!{
|
||||
/// AutomaticReflectRegistrations::add(<type_registration_function>)
|
||||
/// }
|
||||
///
|
||||
/// // Registering collected types
|
||||
/// let mut registry = TypeRegistry::default();
|
||||
/// AutomaticReflectRegistrations::register(&mut registry);
|
||||
/// ```
|
||||
pub struct AutomaticReflectRegistrations;
|
||||
|
||||
pub use inventory::submit as auto_register_function;
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
mod __automatic_type_registration_impl {
|
||||
use super::*;
|
||||
|
||||
pub struct AutomaticReflectRegistrationsImpl(fn(&mut TypeRegistry));
|
||||
pub use inventory::submit as auto_register_function;
|
||||
|
||||
impl AutomaticReflectRegistrations {
|
||||
// Must be const to allow usage in static context
|
||||
pub const fn add(func: fn(&mut TypeRegistry)) -> AutomaticReflectRegistrationsImpl {
|
||||
AutomaticReflectRegistrationsImpl(func)
|
||||
pub struct AutomaticReflectRegistrationsImpl(fn(&mut TypeRegistry));
|
||||
|
||||
impl AutomaticReflectRegistrations {
|
||||
// Must be const to allow usage in static context
|
||||
pub const fn add(func: fn(&mut TypeRegistry)) -> AutomaticReflectRegistrationsImpl {
|
||||
AutomaticReflectRegistrationsImpl(func)
|
||||
}
|
||||
pub fn register(registry: &mut TypeRegistry) {
|
||||
for registration_fn in inventory::iter::<AutomaticReflectRegistrationsImpl> {
|
||||
registration_fn.0(registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn register(registry: &mut TypeRegistry) {
|
||||
for registration_fn in inventory::iter::<AutomaticReflectRegistrationsImpl> {
|
||||
registration_fn.0(registry);
|
||||
|
||||
inventory::collect!(AutomaticReflectRegistrationsImpl);
|
||||
}
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
mod __automatic_type_registration_impl {
|
||||
use super::*;
|
||||
pub use wasm_init::wasm_init as auto_register_function;
|
||||
|
||||
static AUTOMATIC_REFLECT_REGISTRATIONS: std::sync::RwLock<Vec<fn(&mut TypeRegistry)>> =
|
||||
std::sync::RwLock::new(Vec::new());
|
||||
|
||||
impl AutomaticReflectRegistrations {
|
||||
pub fn add(func: fn(&mut TypeRegistry)) {
|
||||
AUTOMATIC_REFLECT_REGISTRATIONS
|
||||
.write()
|
||||
.expect("Failed to get write lock for automatic reflect type registration")
|
||||
.push(func);
|
||||
}
|
||||
pub fn register(registry: &mut TypeRegistry) {
|
||||
// wasm_init must be called at least once to run all init code.
|
||||
// Calling it multiple times is ok and doesn't do anything.
|
||||
wasm_init::wasm_init();
|
||||
|
||||
for registration_fn in AUTOMATIC_REFLECT_REGISTRATIONS
|
||||
.read()
|
||||
.expect("Failed to get read lock for automatic reflect type registration")
|
||||
.iter()
|
||||
{
|
||||
registration_fn(registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory::collect!(AutomaticReflectRegistrationsImpl);
|
||||
pub use __automatic_type_registration_impl::*;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "wasm")]
|
||||
mod __automatic_type_registration_impl {
|
||||
use super::*;
|
||||
pub use wasm_init::wasm_init as auto_register_function;
|
||||
|
||||
static AUTOMATIC_REFLECT_REGISTRATIONS: std::sync::RwLock<Vec<fn(&mut TypeRegistry)>> =
|
||||
std::sync::RwLock::new(Vec::new());
|
||||
|
||||
impl AutomaticReflectRegistrations {
|
||||
pub fn add(func: fn(&mut TypeRegistry)) {
|
||||
AUTOMATIC_REFLECT_REGISTRATIONS
|
||||
.write()
|
||||
.expect("Failed to get write lock for automatic reflect type registration")
|
||||
.push(func);
|
||||
}
|
||||
pub fn register(registry: &mut TypeRegistry) {
|
||||
// wasm_init must be called at least once to run all init code.
|
||||
// Calling it multiple times is ok and doesn't do anything.
|
||||
wasm_init::wasm_init();
|
||||
|
||||
for registration_fn in AUTOMATIC_REFLECT_REGISTRATIONS
|
||||
.read()
|
||||
.expect("Failed to get read lock for automatic reflect type registration")
|
||||
.iter()
|
||||
{
|
||||
registration_fn(registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use __automatic_type_registration_impl::*;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -3045,69 +3051,74 @@ bevy_reflect::tests::Test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_ignore_auto_reflect_registration() {
|
||||
#[derive(Reflect)]
|
||||
#[reflect(no_auto_register)]
|
||||
struct NoAutomaticStruct {
|
||||
a: usize,
|
||||
#[cfg(feature = "auto_register")]
|
||||
mod auto_register_reflect {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_ignore_auto_reflect_registration() {
|
||||
#[derive(Reflect)]
|
||||
#[reflect(no_auto_register)]
|
||||
struct NoAutomaticStruct {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
let mut registry = TypeRegistry::default();
|
||||
registry.register_derived_types();
|
||||
|
||||
assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
|
||||
}
|
||||
|
||||
let mut registry = TypeRegistry::default();
|
||||
registry.register_derived_types();
|
||||
#[test]
|
||||
fn should_auto_register_reflect_for_all_supported_types() {
|
||||
// Struct
|
||||
#[derive(Reflect)]
|
||||
struct StructReflect {
|
||||
a: usize,
|
||||
}
|
||||
|
||||
assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
|
||||
}
|
||||
// ZST struct
|
||||
#[derive(Reflect)]
|
||||
struct ZSTStructReflect;
|
||||
|
||||
#[test]
|
||||
fn should_auto_register_reflect_for_all_supported_types() {
|
||||
// Struct
|
||||
#[derive(Reflect)]
|
||||
struct StructReflect {
|
||||
a: usize,
|
||||
// Tuple struct
|
||||
#[derive(Reflect)]
|
||||
struct TupleStructReflect(pub u32);
|
||||
|
||||
// Enum
|
||||
#[derive(Reflect)]
|
||||
enum EnumReflect {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
// ZST enum
|
||||
#[derive(Reflect)]
|
||||
enum ZSTEnumReflect {}
|
||||
|
||||
// Opaque struct
|
||||
#[derive(Reflect, Clone)]
|
||||
#[reflect(opaque)]
|
||||
struct OpaqueStructReflect {
|
||||
_a: usize,
|
||||
}
|
||||
|
||||
// ZST opaque struct
|
||||
#[derive(Reflect, Clone)]
|
||||
#[reflect(opaque)]
|
||||
struct ZSTOpaqueStructReflect;
|
||||
|
||||
let mut registry = TypeRegistry::default();
|
||||
registry.register_derived_types();
|
||||
|
||||
assert!(registry.contains(TypeId::of::<StructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<EnumReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
|
||||
}
|
||||
|
||||
// ZST struct
|
||||
#[derive(Reflect)]
|
||||
struct ZSTStructReflect;
|
||||
|
||||
// Tuple struct
|
||||
#[derive(Reflect)]
|
||||
struct TupleStructReflect(pub u32);
|
||||
|
||||
// Enum
|
||||
#[derive(Reflect)]
|
||||
enum EnumReflect {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
// ZST enum
|
||||
#[derive(Reflect)]
|
||||
enum ZSTEnumReflect {}
|
||||
|
||||
// Opaque struct
|
||||
#[derive(Reflect, Clone)]
|
||||
#[reflect(opaque)]
|
||||
struct OpaqueStructReflect {
|
||||
_a: usize,
|
||||
}
|
||||
|
||||
// ZST opaque struct
|
||||
#[derive(Reflect, Clone)]
|
||||
#[reflect(opaque)]
|
||||
struct ZSTOpaqueStructReflect;
|
||||
|
||||
let mut registry = TypeRegistry::default();
|
||||
registry.register_derived_types();
|
||||
|
||||
assert!(registry.contains(TypeId::of::<StructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<EnumReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
|
||||
assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
|
||||
}
|
||||
|
||||
#[cfg(feature = "glam")]
|
||||
|
||||
@ -150,8 +150,9 @@ impl TypeRegistry {
|
||||
/// // Its type data
|
||||
/// assert!(type_registry.get_type_data::<ReflectDefault>(TypeId::of::<Foo>()).is_some());
|
||||
/// ```
|
||||
#[cfg(feature = "auto_register")]
|
||||
pub fn register_derived_types(&mut self) {
|
||||
crate::__macro_exports::AutomaticReflectRegistrations::register(self);
|
||||
crate::__macro_exports::auto_register::AutomaticReflectRegistrations::register(self);
|
||||
}
|
||||
|
||||
/// Attempts to register the type `T` if it has not yet been registered already.
|
||||
|
||||
@ -41,6 +41,7 @@ The default feature set enables most of the expected features of a game engine,
|
||||
|ktx2|KTX2 compressed texture support|
|
||||
|multi_threaded|Enables multithreaded parallelism in the engine. Disabling it forces all engine tasks to run on a single thread.|
|
||||
|png|PNG image format support|
|
||||
|reflect_auto_register|Enable automatic reflect registration|
|
||||
|smaa_luts|Include SMAA Look Up Tables KTX2 Files|
|
||||
|sysinfo_plugin|Enables system information diagnostic plugin|
|
||||
|tonemapping_luts|Include tonemapping Look Up Tables KTX2 files. If everything is pink, you need to enable this feature or change the `Tonemapping` method for your `Camera2d` or `Camera3d`.|
|
||||
|
||||
Loading…
Reference in New Issue
Block a user